diff --git a/.gitignore b/.gitignore index 42ed1d4..ae58a28 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,7 @@ report/ Carthage/ Build/ Licenses.plist +fastlane/test-output/ +fastlane/README.md +fastlane/report.xml + diff --git a/.travis.yml b/.travis.yml index d8b8431..fa2431f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,3 +26,5 @@ after_success: - if [ "$FASTLANE_LANE" == "code_coverage" ]; then make post_coverage; fi +notifications: + email: false diff --git a/README.md b/README.md index d693392..d21f3b7 100644 --- a/README.md +++ b/README.md @@ -164,3 +164,16 @@ TrashCanKit().repository("nerdishbynature", name: "octokit.swift") { response in } } ``` + +### Get pull requests for a repository + +```swift +TrashCanKit().pullRequests("nerdishbynature", repoSlug: "octokit.swift") { response in + switch response { + case .Success(let pullRequests, _): + // do something + case .Failure(let error): + // handle any errors + } +} +``` diff --git a/TrashCanKit.xcodeproj/project.pbxproj b/TrashCanKit.xcodeproj/project.pbxproj index caa0cc1..ed2eb64 100644 --- a/TrashCanKit.xcodeproj/project.pbxproj +++ b/TrashCanKit.xcodeproj/project.pbxproj @@ -14,11 +14,8 @@ 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 */; }; @@ -68,18 +65,12 @@ 238EB2051C7C66B700289C37 /* Email.json in Resources */ = {isa = PBXBuildFile; fileRef = 236364A21BE2313B00AA7104 /* Email.json */; }; 238EB2061C7C66B700289C37 /* Repository.json in Resources */ = {isa = PBXBuildFile; fileRef = 236364A31BE2313B00AA7104 /* Repository.json */; }; 238EB2071C7C66B700289C37 /* User.json in Resources */ = {isa = PBXBuildFile; fileRef = 236364A41BE2313B00AA7104 /* User.json */; }; - 238EB2081C7C66B700289C37 /* authorize.json in Resources */ = {isa = PBXBuildFile; fileRef = 231B68571BE9A13C007AE2A6 /* authorize.json */; }; - 238EB2091C7C66B700289C37 /* refresh_token_error.json in Resources */ = {isa = PBXBuildFile; fileRef = 231B685B1BE9A699007AE2A6 /* refresh_token_error.json */; }; 238EB20A1C7C66B700289C37 /* Repositories.json in Resources */ = {isa = PBXBuildFile; fileRef = 231B685D1BE9AA66007AE2A6 /* Repositories.json */; }; - 238EB20B1C7C66B700289C37 /* Me.json in Resources */ = {isa = PBXBuildFile; fileRef = 231B68601BE9AD30007AE2A6 /* Me.json */; }; 238EB20C1C7C66B700289C37 /* Emails.json in Resources */ = {isa = PBXBuildFile; fileRef = 231B68621BE9AD8D007AE2A6 /* Emails.json */; }; 238EB20D1C7C66BD00289C37 /* Email.json in Resources */ = {isa = PBXBuildFile; fileRef = 236364A21BE2313B00AA7104 /* Email.json */; }; 238EB20E1C7C66BD00289C37 /* Repository.json in Resources */ = {isa = PBXBuildFile; fileRef = 236364A31BE2313B00AA7104 /* Repository.json */; }; 238EB20F1C7C66BD00289C37 /* User.json in Resources */ = {isa = PBXBuildFile; fileRef = 236364A41BE2313B00AA7104 /* User.json */; }; - 238EB2101C7C66BD00289C37 /* authorize.json in Resources */ = {isa = PBXBuildFile; fileRef = 231B68571BE9A13C007AE2A6 /* authorize.json */; }; - 238EB2111C7C66BD00289C37 /* refresh_token_error.json in Resources */ = {isa = PBXBuildFile; fileRef = 231B685B1BE9A699007AE2A6 /* refresh_token_error.json */; }; 238EB2121C7C66BD00289C37 /* Repositories.json in Resources */ = {isa = PBXBuildFile; fileRef = 231B685D1BE9AA66007AE2A6 /* Repositories.json */; }; - 238EB2131C7C66BD00289C37 /* Me.json in Resources */ = {isa = PBXBuildFile; fileRef = 231B68601BE9AD30007AE2A6 /* Me.json */; }; 238EB2141C7C66BD00289C37 /* Emails.json in Resources */ = {isa = PBXBuildFile; fileRef = 231B68621BE9AD8D007AE2A6 /* Emails.json */; }; 238EB2151C7C66C200289C37 /* TestHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 236364931BE2301200AA7104 /* TestHelper.swift */; }; 238EB2161C7C66C200289C37 /* RepositoriesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 236364921BE2301200AA7104 /* RepositoriesTests.swift */; }; @@ -106,6 +97,28 @@ 238EB2321C7C67E800289C37 /* Nocilla.framework in Carthage embed */ = {isa = PBXBuildFile; fileRef = 238EB2291C7C677400289C37 /* Nocilla.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 238EB2341C7C67FB00289C37 /* Nocilla.framework in Carthage embed */ = {isa = PBXBuildFile; fileRef = 238EB22E1C7C679A00289C37 /* Nocilla.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 238EB2351C7C67FF00289C37 /* RequestKit.framework in Carthage embed */ = {isa = PBXBuildFile; fileRef = 238EB22B1C7C678300289C37 /* RequestKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 23B38D141C8D2E7A0084450B /* PullRequests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23B38D131C8D2E7A0084450B /* PullRequests.swift */; }; + 23B38D151C8D2E7A0084450B /* PullRequests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23B38D131C8D2E7A0084450B /* PullRequests.swift */; }; + 23B38D161C8D2E7A0084450B /* PullRequests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23B38D131C8D2E7A0084450B /* PullRequests.swift */; }; + 23B38D171C8D2E7A0084450B /* PullRequests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23B38D131C8D2E7A0084450B /* PullRequests.swift */; }; + 23B38D1D1C8D31970084450B /* PullRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23B38D1C1C8D31970084450B /* PullRequestTests.swift */; }; + 23B38D1E1C8D31970084450B /* PullRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23B38D1C1C8D31970084450B /* PullRequestTests.swift */; }; + 23B38D1F1C8D31970084450B /* PullRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23B38D1C1C8D31970084450B /* PullRequestTests.swift */; }; + 23B38D251C8D31FC0084450B /* PullRequest.json in Resources */ = {isa = PBXBuildFile; fileRef = 23B38D241C8D31FC0084450B /* PullRequest.json */; }; + 23B38D261C8D31FC0084450B /* PullRequest.json in Resources */ = {isa = PBXBuildFile; fileRef = 23B38D241C8D31FC0084450B /* PullRequest.json */; }; + 23B38D271C8D31FC0084450B /* PullRequest.json in Resources */ = {isa = PBXBuildFile; fileRef = 23B38D241C8D31FC0084450B /* PullRequest.json */; }; + 23B38D2C1C8D433B0084450B /* authorize.json in Resources */ = {isa = PBXBuildFile; fileRef = 23B38D281C8D433B0084450B /* authorize.json */; }; + 23B38D2D1C8D433B0084450B /* authorize.json in Resources */ = {isa = PBXBuildFile; fileRef = 23B38D281C8D433B0084450B /* authorize.json */; }; + 23B38D2E1C8D433B0084450B /* authorize.json in Resources */ = {isa = PBXBuildFile; fileRef = 23B38D281C8D433B0084450B /* authorize.json */; }; + 23B38D2F1C8D433B0084450B /* Me.json in Resources */ = {isa = PBXBuildFile; fileRef = 23B38D291C8D433B0084450B /* Me.json */; }; + 23B38D301C8D433B0084450B /* Me.json in Resources */ = {isa = PBXBuildFile; fileRef = 23B38D291C8D433B0084450B /* Me.json */; }; + 23B38D311C8D433B0084450B /* Me.json in Resources */ = {isa = PBXBuildFile; fileRef = 23B38D291C8D433B0084450B /* Me.json */; }; + 23B38D321C8D433B0084450B /* PullRequests.json in Resources */ = {isa = PBXBuildFile; fileRef = 23B38D2A1C8D433B0084450B /* PullRequests.json */; }; + 23B38D331C8D433B0084450B /* PullRequests.json in Resources */ = {isa = PBXBuildFile; fileRef = 23B38D2A1C8D433B0084450B /* PullRequests.json */; }; + 23B38D341C8D433B0084450B /* PullRequests.json in Resources */ = {isa = PBXBuildFile; fileRef = 23B38D2A1C8D433B0084450B /* PullRequests.json */; }; + 23B38D351C8D433B0084450B /* refresh_token_error.json in Resources */ = {isa = PBXBuildFile; fileRef = 23B38D2B1C8D433B0084450B /* refresh_token_error.json */; }; + 23B38D361C8D433B0084450B /* refresh_token_error.json in Resources */ = {isa = PBXBuildFile; fileRef = 23B38D2B1C8D433B0084450B /* refresh_token_error.json */; }; + 23B38D371C8D433B0084450B /* refresh_token_error.json in Resources */ = {isa = PBXBuildFile; fileRef = 23B38D2B1C8D433B0084450B /* refresh_token_error.json */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -179,11 +192,8 @@ 231B68511BE9989C007AE2A6 /* TokenConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokenConfiguration.swift; sourceTree = ""; }; 231B68531BE998C7007AE2A6 /* OAuthRouter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OAuthRouter.swift; sourceTree = ""; }; 231B68551BE9997C007AE2A6 /* ConfigurationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigurationTests.swift; sourceTree = ""; }; - 231B68571BE9A13C007AE2A6 /* authorize.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = authorize.json; sourceTree = ""; }; 231B68591BE9A3DD007AE2A6 /* TokenTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokenTests.swift; sourceTree = ""; }; - 231B685B1BE9A699007AE2A6 /* refresh_token_error.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = refresh_token_error.json; sourceTree = ""; }; 231B685D1BE9AA66007AE2A6 /* Repositories.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = Repositories.json; path = Fixtures/Repositories.json; sourceTree = ""; }; - 231B68601BE9AD30007AE2A6 /* Me.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Me.json; sourceTree = ""; }; 231B68621BE9AD8D007AE2A6 /* Emails.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = Emails.json; path = Fixtures/Emails.json; sourceTree = ""; }; 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 = ""; }; @@ -212,6 +222,13 @@ 238EB2291C7C677400289C37 /* Nocilla.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nocilla.framework; path = Carthage/Build/tvOS/Nocilla.framework; sourceTree = ""; }; 238EB22B1C7C678300289C37 /* RequestKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RequestKit.framework; path = Carthage/Build/Mac/RequestKit.framework; sourceTree = ""; }; 238EB22E1C7C679A00289C37 /* Nocilla.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nocilla.framework; path = Carthage/Build/Mac/Nocilla.framework; sourceTree = ""; }; + 23B38D131C8D2E7A0084450B /* PullRequests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PullRequests.swift; sourceTree = ""; }; + 23B38D1C1C8D31970084450B /* PullRequestTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PullRequestTests.swift; sourceTree = ""; }; + 23B38D241C8D31FC0084450B /* PullRequest.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = PullRequest.json; path = Fixtures/PullRequest.json; sourceTree = ""; }; + 23B38D281C8D433B0084450B /* authorize.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = authorize.json; path = Fixtures/authorize.json; sourceTree = ""; }; + 23B38D291C8D433B0084450B /* Me.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = Me.json; path = Fixtures/Me.json; sourceTree = ""; }; + 23B38D2A1C8D433B0084450B /* PullRequests.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = PullRequests.json; path = Fixtures/PullRequests.json; sourceTree = ""; }; + 23B38D2B1C8D433B0084450B /* refresh_token_error.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = refresh_token_error.json; path = Fixtures/refresh_token_error.json; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -314,6 +331,7 @@ 231069D21C06BE3400101BCC /* String+QueryParameters.swift */, 231069D41C06BE6D00101BCC /* Dictionary+Additions.swift */, 2363648C1BE22FCC00AA7104 /* Token.swift */, + 23B38D131C8D2E7A0084450B /* PullRequests.swift */, 2363648D1BE22FCC00AA7104 /* User.swift */, 236364751BE22F1000AA7104 /* Info.plist */, ); @@ -328,6 +346,7 @@ 236364951BE2301200AA7104 /* UserTests.swift */, 231B68551BE9997C007AE2A6 /* ConfigurationTests.swift */, 231B68591BE9A3DD007AE2A6 /* TokenTests.swift */, + 23B38D1C1C8D31970084450B /* PullRequestTests.swift */, 236364A11BE2313200AA7104 /* Fixtures */, 236364811BE22F1000AA7104 /* Info.plist */, ); @@ -340,11 +359,13 @@ 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 */, + 23B38D241C8D31FC0084450B /* PullRequest.json */, + 23B38D281C8D433B0084450B /* authorize.json */, + 23B38D291C8D433B0084450B /* Me.json */, + 23B38D2A1C8D433B0084450B /* PullRequests.json */, + 23B38D2B1C8D433B0084450B /* refresh_token_error.json */, ); name = Fixtures; sourceTree = ""; @@ -598,13 +619,15 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 231B68611BE9AD30007AE2A6 /* Me.json in Resources */, + 23B38D321C8D433B0084450B /* PullRequests.json in Resources */, 231B685F1BE9AAC6007AE2A6 /* Repositories.json in Resources */, - 231B68581BE9A13C007AE2A6 /* authorize.json in Resources */, - 231B685C1BE9A699007AE2A6 /* refresh_token_error.json in Resources */, + 23B38D2F1C8D433B0084450B /* Me.json in Resources */, 236364A51BE2313B00AA7104 /* Email.json in Resources */, 236364A71BE2313B00AA7104 /* User.json in Resources */, 231B68631BE9AD8D007AE2A6 /* Emails.json in Resources */, + 23B38D351C8D433B0084450B /* refresh_token_error.json in Resources */, + 23B38D2C1C8D433B0084450B /* authorize.json in Resources */, + 23B38D251C8D31FC0084450B /* PullRequest.json in Resources */, 236364A61BE2313B00AA7104 /* Repository.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -627,13 +650,15 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 23B38D331C8D433B0084450B /* PullRequests.json in Resources */, 238EB2051C7C66B700289C37 /* Email.json in Resources */, + 23B38D301C8D433B0084450B /* Me.json in Resources */, 238EB2061C7C66B700289C37 /* Repository.json in Resources */, 238EB2071C7C66B700289C37 /* User.json in Resources */, - 238EB2081C7C66B700289C37 /* authorize.json in Resources */, - 238EB2091C7C66B700289C37 /* refresh_token_error.json in Resources */, 238EB20A1C7C66B700289C37 /* Repositories.json in Resources */, - 238EB20B1C7C66B700289C37 /* Me.json in Resources */, + 23B38D361C8D433B0084450B /* refresh_token_error.json in Resources */, + 23B38D2D1C8D433B0084450B /* authorize.json in Resources */, + 23B38D261C8D31FC0084450B /* PullRequest.json in Resources */, 238EB20C1C7C66B700289C37 /* Emails.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -649,13 +674,15 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 23B38D341C8D433B0084450B /* PullRequests.json in Resources */, 238EB20D1C7C66BD00289C37 /* Email.json in Resources */, + 23B38D311C8D433B0084450B /* Me.json in Resources */, 238EB20E1C7C66BD00289C37 /* Repository.json in Resources */, 238EB20F1C7C66BD00289C37 /* User.json in Resources */, - 238EB2101C7C66BD00289C37 /* authorize.json in Resources */, - 238EB2111C7C66BD00289C37 /* refresh_token_error.json in Resources */, 238EB2121C7C66BD00289C37 /* Repositories.json in Resources */, - 238EB2131C7C66BD00289C37 /* Me.json in Resources */, + 23B38D371C8D433B0084450B /* refresh_token_error.json in Resources */, + 23B38D2E1C8D433B0084450B /* authorize.json in Resources */, + 23B38D271C8D31FC0084450B /* PullRequest.json in Resources */, 238EB2141C7C66BD00289C37 /* Emails.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -677,6 +704,7 @@ 231B68541BE998C7007AE2A6 /* OAuthRouter.swift in Sources */, 2363648F1BE22FCC00AA7104 /* Repositories.swift in Sources */, 231069D51C06BE6D00101BCC /* Dictionary+Additions.swift in Sources */, + 23B38D141C8D2E7A0084450B /* PullRequests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -688,6 +716,7 @@ 231B685A1BE9A3DD007AE2A6 /* TokenTests.swift in Sources */, 236364961BE2301200AA7104 /* RepositoriesTests.swift in Sources */, 231B68561BE9997C007AE2A6 /* ConfigurationTests.swift in Sources */, + 23B38D1D1C8D31970084450B /* PullRequestTests.swift in Sources */, 236364971BE2301200AA7104 /* TestHelper.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -706,6 +735,7 @@ 238EB1F11C7C669400289C37 /* Dictionary+Additions.swift in Sources */, 238EB1F21C7C669400289C37 /* Token.swift in Sources */, 238EB1F31C7C669400289C37 /* User.swift in Sources */, + 23B38D151C8D2E7A0084450B /* PullRequests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -723,6 +753,7 @@ 238EB1FC1C7C66A500289C37 /* Dictionary+Additions.swift in Sources */, 238EB1FD1C7C66A500289C37 /* Token.swift in Sources */, 238EB1FE1C7C66A500289C37 /* User.swift in Sources */, + 23B38D161C8D2E7A0084450B /* PullRequests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -734,6 +765,7 @@ 238EB2011C7C66B100289C37 /* RepositoriesTests.swift in Sources */, 238EB2021C7C66B100289C37 /* UserTests.swift in Sources */, 238EB2031C7C66B100289C37 /* ConfigurationTests.swift in Sources */, + 23B38D1E1C8D31970084450B /* PullRequestTests.swift in Sources */, 238EB2041C7C66B100289C37 /* TokenTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -752,6 +784,7 @@ 238EB2211C7C66C800289C37 /* Dictionary+Additions.swift in Sources */, 238EB2221C7C66C800289C37 /* Token.swift in Sources */, 238EB2231C7C66C800289C37 /* User.swift in Sources */, + 23B38D171C8D2E7A0084450B /* PullRequests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -763,6 +796,7 @@ 238EB2161C7C66C200289C37 /* RepositoriesTests.swift in Sources */, 238EB2171C7C66C200289C37 /* UserTests.swift in Sources */, 238EB2181C7C66C200289C37 /* ConfigurationTests.swift in Sources */, + 23B38D1F1C8D31970084450B /* PullRequestTests.swift in Sources */, 238EB2191C7C66C200289C37 /* TokenTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/TrashCanKit/PullRequests.swift b/TrashCanKit/PullRequests.swift new file mode 100644 index 0000000..4a06150 --- /dev/null +++ b/TrashCanKit/PullRequests.swift @@ -0,0 +1,78 @@ +import Foundation +import RequestKit + +@objc public class PullRequest: NSObject { + public var id: String + public var pullRequestDescription: String? + public var title: String? + public var state: String? + public var author: User? + + public init(json: [String: AnyObject]) { + if let id = json["id"] { + self.id = String(id) + title = json["title"] as? String + pullRequestDescription = json["description"] as? String + state = json["state"] as? String + author = User(json["author"] as? [String: AnyObject] ?? [:]) + } else { + id = "-1" + } + } +} + +// MARK: request + +public extension TrashCanKit { + public func pullRequests(owner: String, repoSlug: String, nextParameters: [String: String] = [:], completion: (response: PaginatedResponse<[PullRequest]>) -> Void) { + let router = PullRequestRouter.ReadPullRequests(configuration, owner, repoSlug, nextParameters) + router.loadJSON([String: AnyObject].self) { json, error in + if let error = error { + completion(response: PaginatedResponse.Failure(error)) + } + + if let json = json, values = json["values"] as? [[String: AnyObject]] { + let repos = values.map { PullRequest(json: $0) } + if let nextURL = json["next"] as? String, parameterString = nextURL.componentsSeparatedByString("?").last { + completion(response: PaginatedResponse.Success(values: repos, nextParameters: parameterString.tkk_queryParameters)) + } else { + completion(response: PaginatedResponse.Success(values: repos, nextParameters: [String: String]())) + } + } + } + } +} + +// MARK: Router + +public enum PullRequestRouter: Router { + case ReadPullRequests(Configuration, String, String, [String: String]) + + public var configuration: Configuration { + switch self { + case .ReadPullRequests(let config, _, _, _): return config + } + } + + public var method: HTTPMethod { + return .GET + } + + public var encoding: HTTPEncoding { + return .URL + } + + public var params: [String: String] { + switch self { + case .ReadPullRequests(_, _, _, let nextParameters): + return nextParameters + } + } + + public var path: String { + switch self { + case .ReadPullRequests(_, let owner, let repoSlug, _): + return "/repositories/\(owner)/\(repoSlug)/pullrequests" + } + } +} diff --git a/TrashCanKit/User.swift b/TrashCanKit/User.swift index e8b25b1..fa04d26 100644 --- a/TrashCanKit/User.swift +++ b/TrashCanKit/User.swift @@ -2,17 +2,18 @@ import Foundation import RequestKit @objc public class User: NSObject { - public let id: String - public var login: String? + public let id: String? + public var login: String public var name: String? public init(_ json: [String: AnyObject]) { - if let id = json["uuid"] as? String { - self.id = id - login = json["username"] as? String + if let username = json["username"] as? String { + id = json["uuid"] as? String + login = username name = json["display_name"] as? String } else { id = "-1" + login = "" } } } diff --git a/TrashCanKitTests/Me.json b/TrashCanKitTests/Fixtures/Me.json similarity index 100% rename from TrashCanKitTests/Me.json rename to TrashCanKitTests/Fixtures/Me.json diff --git a/TrashCanKitTests/Fixtures/PullRequest.json b/TrashCanKitTests/Fixtures/PullRequest.json new file mode 100644 index 0000000..50282ed --- /dev/null +++ b/TrashCanKitTests/Fixtures/PullRequest.json @@ -0,0 +1,106 @@ +{ + "description": "![img](https://cloudup.com/c7ZJtChLw9J+)\r\n\r\n## Removing:\r\n\r\n* Notifications\r\n* Email\r\n* Change password\r\n* Sessions\r\n\r\n## Renaming: \r\n\r\n* Change username\r\n* Delete account (rename to delete team)\r\n\r\n", + "links": { + "decline": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767/decline" + }, + "commits": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767/commits" + }, + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767" + }, + "comments": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767/comments" + }, + "patch": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767/patch" + }, + "merge": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767/merge" + }, + "html": { + "href": "https://api.bitbucket.org/bitbucket/bitbucket/pull-request/3767" + }, + "activity": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767/activity" + }, + "diff": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767/diff" + }, + "approve": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767/approve" + } + }, + "author": { + "username": "mfrauenholtz", + "display_name": "Michael Frauenholtz", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/users/mfrauenholtz" + }, + "avatar": { + "href": "https://bitbucket-staging-assetroot.s3.amazonaws.com/c/photos/2013/Aug/24/mfrauenholtz-avatar-1858533797-5_avatar.png" + } + } + }, + "close_source_branch": true, + "title": "BB-9500: Remove certain admin links for Team accounts", + "destination": { + "commit": { + "hash": "e04099ba977c", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/commit/e04099ba977c" + } + } + }, + "repository": { + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket" + }, + "avatar": { + "href": "https://bitbucket-staging-assetroot.s3.amazonaws.com/c/photos/2013/Sep/27/bitbucket-logo-1832464563-7_avatar.png" + } + }, + "full_name": "bitbucket/bitbucket", + "name": "bitbucket" + }, + "branch": { + "name": "staging" + } + }, + "reason": "", + "closed_by": null, + "source": { + "commit": { + "hash": "2a81a1edc0c2", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/commit/2a81a1edc0c2" + } + } + }, + "repository": { + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket" + }, + "avatar": { + "href": "https://bitbucket-staging-assetroot.s3.amazonaws.com/c/photos/2013/Sep/27/bitbucket-logo-1832464563-7_avatar.png" + } + }, + "full_name": "bitbucket/bitbucket", + "name": "bitbucket" + }, + "branch": { + "name": "mfrauenholtz/team-removal/admin-links" + } + }, + "state": "OPEN", + "created_on": "2013-11-05T23:59:26.480984+00:00", + "updated_on": "2013-11-07T00:17:41.061613+00:00", + "merge_commit": null, + "id": 3767 +} \ No newline at end of file diff --git a/TrashCanKitTests/Fixtures/PullRequests.json b/TrashCanKitTests/Fixtures/PullRequests.json new file mode 100644 index 0000000..fc4a888 --- /dev/null +++ b/TrashCanKitTests/Fixtures/PullRequests.json @@ -0,0 +1,114 @@ +{ + "pagelen": 1, + "next": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests?pagelen=1&page=2", + "values": [ + { + "description": "![img](https://cloudup.com/c7ZJtChLw9J+)\r\n\r\n## Removing:\r\n\r\n* Notifications\r\n* Email\r\n* Change password\r\n* Sessions\r\n\r\n## Renaming: \r\n\r\n* Change username\r\n* Delete account (rename to delete team)\r\n\r\n", + "links": { + "decline": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767/decline" + }, + "commits": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767/commits" + }, + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767" + }, + "comments": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767/comments" + }, + "patch": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767/patch" + }, + "merge": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767/merge" + }, + "html": { + "href": "https://api.bitbucket.org/bitbucket/bitbucket/pull-request/3767" + }, + "activity": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767/activity" + }, + "diff": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767/diff" + }, + "approve": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/pullrequests/3767/approve" + } + }, + "author": { + "username": "mfrauenholtz", + "display_name": "Michael Frauenholtz", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/users/mfrauenholtz" + }, + "avatar": { + "href": "https://bitbucket-staging-assetroot.s3.amazonaws.com/c/photos/2013/Aug/24/mfrauenholtz-avatar-1858533797-5_avatar.png" + } + } + }, + "close_source_branch": true, + "title": "BB-9500: Remove certain admin links for Team accounts", + "destination": { + "commit": { + "hash": "e04099ba977c", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/commit/e04099ba977c" + } + } + }, + "repository": { + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket" + }, + "avatar": { + "href": "https://bitbucket-staging-assetroot.s3.amazonaws.com/c/photos/2013/Sep/27/bitbucket-logo-1832464563-7_avatar.png" + } + }, + "full_name": "bitbucket/bitbucket", + "name": "bitbucket" + }, + "branch": { + "name": "staging" + } + }, + "reason": "", + "closed_by": null, + "source": { + "commit": { + "hash": "2a81a1edc0c2", + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket/commit/2a81a1edc0c2" + } + } + }, + "repository": { + "links": { + "self": { + "href": "https://api.bitbucket.org/2.0/repositories/bitbucket/bitbucket" + }, + "avatar": { + "href": "https://bitbucket-staging-assetroot.s3.amazonaws.com/c/photos/2013/Sep/27/bitbucket-logo-1832464563-7_avatar.png" + } + }, + "full_name": "bitbucket/bitbucket", + "name": "bitbucket" + }, + "branch": { + "name": "mfrauenholtz/team-removal/admin-links" + } + }, + "state": "OPEN", + "created_on": "2013-11-05T23:59:26.480984+00:00", + "updated_on": "2013-11-07T00:17:41.061613+00:00", + "merge_commit": null, + "id": 3767 + } + ], + "page": 1, + "size": 12 +} diff --git a/TrashCanKitTests/authorize.json b/TrashCanKitTests/Fixtures/authorize.json similarity index 100% rename from TrashCanKitTests/authorize.json rename to TrashCanKitTests/Fixtures/authorize.json diff --git a/TrashCanKitTests/refresh_token_error.json b/TrashCanKitTests/Fixtures/refresh_token_error.json similarity index 100% rename from TrashCanKitTests/refresh_token_error.json rename to TrashCanKitTests/Fixtures/refresh_token_error.json diff --git a/TrashCanKitTests/PullRequestTests.swift b/TrashCanKitTests/PullRequestTests.swift new file mode 100644 index 0000000..c52871e --- /dev/null +++ b/TrashCanKitTests/PullRequestTests.swift @@ -0,0 +1,68 @@ +import XCTest +import Nocilla +import TrashCanKit + +class PullRequestTests: XCTestCase { + override func setUp() { + super.setUp() + LSNocilla.sharedInstance().start() + } + + override func tearDown() { + super.tearDown() + LSNocilla.sharedInstance().clearStubs() + LSNocilla.sharedInstance().stop() + } + + func testConstructFromJSON() { + let repository = PullRequest(json: TestHelper.loadJSON("PullRequest")) + XCTAssertEqual(repository.id, "3767") + XCTAssertEqual(repository.author?.login, "mfrauenholtz") + XCTAssertEqual(repository.pullRequestDescription, "![img](https://cloudup.com/c7ZJtChLw9J+)\r\n\r\n## Removing:\r\n\r\n* Notifications\r\n* Email\r\n* Change password\r\n* Sessions\r\n\r\n## Renaming: \r\n\r\n* Change username\r\n* Delete account (rename to delete team)\r\n\r\n") + XCTAssertEqual(repository.state, "OPEN") + } + + func testFailToConstructFromJSON() { + let repository = PullRequest(json: [:]) + XCTAssertEqual(repository.id, "-1") + } + + func testGetPullRequests() { + let tokenConfig = TokenConfiguration("123456", refreshToken: "7890") + stubRequest("GET", "https://bitbucket.org/api/2.0/repositories/nerdishbynature/octokit.swift/pullrequests?access_token=123456").andReturn(200).withBody(TestHelper.loadJSONString("PullRequests")) + let expectation = expectationWithDescription("get_pull_requests") + TrashCanKit(tokenConfig).pullRequests("nerdishbynature", repoSlug: "octokit.swift") { response in + switch response { + case .Success(let pullRequests, let nextParameters): + XCTAssertEqual(nextParameters["page"], "2") + XCTAssertEqual(pullRequests.count, 1) + expectation.fulfill() + case .Failure: + XCTAssertFalse(true) + expectation.fulfill() + } + } + waitForExpectationsWithTimeout(1) { error in + XCTAssertNil(error) + } + } + + func testGetPullRequestsWithError() { + let tokenConfig = TokenConfiguration("123456", refreshToken: "7890") + stubRequest("GET", "https://bitbucket.org/api/2.0/repositories/nerdishbynature/octokit.swift/pullrequests?access_token=123456").andReturn(404) + let expectation = expectationWithDescription("get_pull_requests") + TrashCanKit(tokenConfig).pullRequests("nerdishbynature", repoSlug: "octokit.swift") { response in + switch response { + case .Success: + XCTAssertTrue(false) + expectation.fulfill() + case .Failure(let error): + XCTAssertEqual((error as NSError).code, 404) + expectation.fulfill() + } + } + waitForExpectationsWithTimeout(1) { error in + XCTAssertNil(error) + } + } +}