Adds unit tests for adding a new feed with Feedly. #1300
This commit is contained in:
parent
7563d1b2c6
commit
d9a2ca8e7e
@ -74,7 +74,6 @@
|
||||
844B297F210CE37E004020B3 /* UnreadCountProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844B297E210CE37E004020B3 /* UnreadCountProvider.swift */; };
|
||||
844B2981210CE3BF004020B3 /* RSWeb.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 844B2980210CE3BF004020B3 /* RSWeb.framework */; };
|
||||
8469F81C1F6DD15E0084783E /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848935101F62486800CEBD24 /* Account.swift */; };
|
||||
846CA1882392349E00B55117 /* SyncDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846CA1872392349E00B55117 /* SyncDatabase.framework */; };
|
||||
846E77451F6EF9B900A165E2 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419740D1F6DD25F006346C4 /* Container.swift */; };
|
||||
846E774F1F6EF9C000A165E2 /* LocalAccountDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419742C1F6DDE84006346C4 /* LocalAccountDelegate.swift */; };
|
||||
846E77501F6EF9C400A165E2 /* LocalAccountRefresher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419742D1F6DDE96006346C4 /* LocalAccountRefresher.swift */; };
|
||||
@ -127,6 +126,7 @@
|
||||
9E7299D9235062A200DAEFB7 /* FeedlyResourceProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7299D8235062A200DAEFB7 /* FeedlyResourceProviding.swift */; };
|
||||
9E784EBE237E890600099B1B /* FeedlyLogoutOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E784EBD237E890600099B1B /* FeedlyLogoutOperation.swift */; };
|
||||
9E784EC0237E8BE100099B1B /* FeedlyLogoutOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E784EBF237E8BE100099B1B /* FeedlyLogoutOperationTests.swift */; };
|
||||
9E79F7742395C9F00031DB98 /* feedly-add-new-feed in Resources */ = {isa = PBXBuildFile; fileRef = 9E79F7732395C9EF0031DB98 /* feedly-add-new-feed */; };
|
||||
9E7F88AC235EDDC2009AB9DF /* FeedlyCreateFeedsForCollectionFoldersOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7F88AB235EDDC2009AB9DF /* FeedlyCreateFeedsForCollectionFoldersOperationTests.swift */; };
|
||||
9E7F88AE235FBB11009AB9DF /* FeedlyGetStreamContentsOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7F88AD235FBB11009AB9DF /* FeedlyGetStreamContentsOperationTests.swift */; };
|
||||
9E84DC472359A23200D6E809 /* FeedlySyncUnreadStatusesOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E84DC462359A23200D6E809 /* FeedlySyncUnreadStatusesOperation.swift */; };
|
||||
@ -142,6 +142,7 @@
|
||||
9EA643CF2391D3560018A28C /* FeedlyAddExistingFeedOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA643CE2391D3550018A28C /* FeedlyAddExistingFeedOperation.swift */; };
|
||||
9EA643D3239305680018A28C /* FeedlySearchOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA643D2239305680018A28C /* FeedlySearchOperation.swift */; };
|
||||
9EA643D5239306AC0018A28C /* FeedlyFeedsSearchResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA643D4239306AC0018A28C /* FeedlyFeedsSearchResponse.swift */; };
|
||||
9EA643D923945CE00018A28C /* FeedlyAddNewFeedOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA643D823945CE00018A28C /* FeedlyAddNewFeedOperationTests.swift */; };
|
||||
9EAEC60C2332FE830085D7C9 /* FeedlyCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAEC60B2332FE830085D7C9 /* FeedlyCollection.swift */; };
|
||||
9EAEC60E2332FEC20085D7C9 /* FeedlyFeed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAEC60D2332FEC20085D7C9 /* FeedlyFeed.swift */; };
|
||||
9EAEC624233315F60085D7C9 /* FeedlyEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAEC623233315F60085D7C9 /* FeedlyEntry.swift */; };
|
||||
@ -295,7 +296,6 @@
|
||||
844B297C2106C7EC004020B3 /* WebFeed.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WebFeed.swift; sourceTree = "<group>"; };
|
||||
844B297E210CE37E004020B3 /* UnreadCountProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnreadCountProvider.swift; sourceTree = "<group>"; };
|
||||
844B2980210CE3BF004020B3 /* RSWeb.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RSWeb.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
846CA1872392349E00B55117 /* SyncDatabase.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SyncDatabase.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
846E77531F6F00E300A165E2 /* AccountManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountManager.swift; sourceTree = "<group>"; };
|
||||
848934F61F62484F00CEBD24 /* Account.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Account.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
848934FA1F62484F00CEBD24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
@ -349,6 +349,7 @@
|
||||
9E7299D8235062A200DAEFB7 /* FeedlyResourceProviding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedlyResourceProviding.swift; sourceTree = "<group>"; };
|
||||
9E784EBD237E890600099B1B /* FeedlyLogoutOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedlyLogoutOperation.swift; sourceTree = "<group>"; };
|
||||
9E784EBF237E8BE100099B1B /* FeedlyLogoutOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedlyLogoutOperationTests.swift; sourceTree = "<group>"; };
|
||||
9E79F7732395C9EF0031DB98 /* feedly-add-new-feed */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "feedly-add-new-feed"; sourceTree = "<group>"; };
|
||||
9E7F88AB235EDDC2009AB9DF /* FeedlyCreateFeedsForCollectionFoldersOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedlyCreateFeedsForCollectionFoldersOperationTests.swift; sourceTree = "<group>"; };
|
||||
9E7F88AD235FBB11009AB9DF /* FeedlyGetStreamContentsOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedlyGetStreamContentsOperationTests.swift; sourceTree = "<group>"; };
|
||||
9E84DC462359A23200D6E809 /* FeedlySyncUnreadStatusesOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedlySyncUnreadStatusesOperation.swift; sourceTree = "<group>"; };
|
||||
@ -364,6 +365,7 @@
|
||||
9EA643CE2391D3550018A28C /* FeedlyAddExistingFeedOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedlyAddExistingFeedOperation.swift; sourceTree = "<group>"; };
|
||||
9EA643D2239305680018A28C /* FeedlySearchOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedlySearchOperation.swift; sourceTree = "<group>"; };
|
||||
9EA643D4239306AC0018A28C /* FeedlyFeedsSearchResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedlyFeedsSearchResponse.swift; sourceTree = "<group>"; };
|
||||
9EA643D823945CE00018A28C /* FeedlyAddNewFeedOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedlyAddNewFeedOperationTests.swift; sourceTree = "<group>"; };
|
||||
9EAEC60B2332FE830085D7C9 /* FeedlyCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedlyCollection.swift; sourceTree = "<group>"; };
|
||||
9EAEC60D2332FEC20085D7C9 /* FeedlyFeed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedlyFeed.swift; sourceTree = "<group>"; };
|
||||
9EAEC623233315F60085D7C9 /* FeedlyEntry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedlyEntry.swift; sourceTree = "<group>"; };
|
||||
@ -667,6 +669,8 @@
|
||||
9E1773DA234593CF0056A5A8 /* FeedlyResourceIdTests.swift */,
|
||||
9E0260CA236FF99A00D122D3 /* FeedlyRefreshAccessTokenOperationTests.swift */,
|
||||
9E784EBF237E8BE100099B1B /* FeedlyLogoutOperationTests.swift */,
|
||||
9EA643D823945CE00018A28C /* FeedlyAddNewFeedOperationTests.swift */,
|
||||
9E79F7732395C9EF0031DB98 /* feedly-add-new-feed */,
|
||||
9E5ABE99236BE6BC00B5DE9F /* feedly-1-initial */,
|
||||
9EC804E4236C1A7F0057CFCB /* feedly-2-changestatuses */,
|
||||
9EC804E6236C1BA60057CFCB /* feedly-3-changestatusesagain */,
|
||||
@ -933,6 +937,7 @@
|
||||
9EC804E5236C1A7F0057CFCB /* feedly-2-changestatuses in Resources */,
|
||||
51D5875A227F630B00900287 /* tags_delete.json in Resources */,
|
||||
9EC804E7236C1BA60057CFCB /* feedly-3-changestatusesagain in Resources */,
|
||||
9E79F7742395C9F00031DB98 /* feedly-add-new-feed in Resources */,
|
||||
9EC804EF236C20DD0057CFCB /* feedly_macintosh_initial.json in Resources */,
|
||||
5165D71722821C2400D9D53D /* taggings_add.json in Resources */,
|
||||
5165D71622821C2400D9D53D /* taggings_delete.json in Resources */,
|
||||
@ -1096,6 +1101,7 @@
|
||||
9E489E912360ED30004372EE /* FeedlyOrganiseParsedItemsByFeedOperationTests.swift in Sources */,
|
||||
9E0260CB236FF99A00D122D3 /* FeedlyRefreshAccessTokenOperationTests.swift in Sources */,
|
||||
9E1FF8622368219B00834C24 /* TestGetPagedStreamIdsService.swift in Sources */,
|
||||
9EA643D923945CE00018A28C /* FeedlyAddNewFeedOperationTests.swift in Sources */,
|
||||
9E7F88AC235EDDC2009AB9DF /* FeedlyCreateFeedsForCollectionFoldersOperationTests.swift in Sources */,
|
||||
9E03C11E235D976500FB6D9E /* FeedlyGetCollectionsOperationTests.swift in Sources */,
|
||||
9E85C8E62366FED600D0F1F7 /* TestGetStreamContentsService.swift in Sources */,
|
||||
|
@ -0,0 +1,334 @@
|
||||
//
|
||||
// FeedlyAddNewFeedOperationTests.swift
|
||||
// AccountTests
|
||||
//
|
||||
// Created by Kiel Gillard on 2/12/19.
|
||||
// Copyright © 2019 Ranchero Software, LLC. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import Account
|
||||
import RSWeb
|
||||
|
||||
class FeedlyAddNewFeedOperationTests: XCTestCase {
|
||||
|
||||
private var account: Account!
|
||||
private let support = FeedlyTestSupport()
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
account = support.makeTestAccount()
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
if let account = account {
|
||||
support.destroy(account)
|
||||
}
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
private var transport = TestTransport()
|
||||
lazy var caller: FeedlyAPICaller = {
|
||||
let caller = FeedlyAPICaller(transport: transport, api: .sandbox)
|
||||
caller.credentials = support.accessToken
|
||||
return caller
|
||||
}()
|
||||
|
||||
private func getFolderByLoadingInitialContent() -> Folder? {
|
||||
let subdirectory = "feedly-add-new-feed"
|
||||
let provider = InitialMockResponseProvider(findingMocksIn: subdirectory)
|
||||
|
||||
transport.mockResponseFileUrlProvider = provider
|
||||
let getCollections = FeedlyGetCollectionsOperation(service: caller, log: support.log)
|
||||
|
||||
let mirrorCollectionsAsFolders = FeedlyMirrorCollectionsAsFoldersOperation(account: account, collectionsProvider: getCollections, log: support.log)
|
||||
mirrorCollectionsAsFolders.addDependency(getCollections)
|
||||
|
||||
let createFolders = FeedlyCreateFeedsForCollectionFoldersOperation(account: account, feedsAndFoldersProvider: mirrorCollectionsAsFolders, log: support.log)
|
||||
createFolders.addDependency(mirrorCollectionsAsFolders)
|
||||
|
||||
let completionExpectation = expectation(description: "Did Finish")
|
||||
createFolders.completionBlock = {
|
||||
completionExpectation.fulfill()
|
||||
}
|
||||
|
||||
OperationQueue.main.addOperations([getCollections, mirrorCollectionsAsFolders, createFolders], waitUntilFinished: false)
|
||||
|
||||
waitForExpectations(timeout: 2)
|
||||
|
||||
support.checkFoldersAndFeeds(in: account, againstCollectionsAndFeedsInJSONNamed: "emptyCollections", subdirectory: subdirectory)
|
||||
|
||||
guard let folder = account.folders?.first else {
|
||||
XCTFail("Unable to load test folder to add a feed into.")
|
||||
return nil
|
||||
}
|
||||
|
||||
XCTAssertEqual(folder.topLevelWebFeeds.count, 0)
|
||||
|
||||
return folder
|
||||
}
|
||||
|
||||
func expectationForCompletion(of progress: DownloadProgress) -> XCTestExpectation {
|
||||
return expectation(forNotification: .DownloadProgressDidChange, object: progress) { notification -> Bool in
|
||||
guard let progress = notification.object as? DownloadProgress else {
|
||||
return false
|
||||
}
|
||||
// We want to assert the progress completes.
|
||||
if progress.isComplete {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
let searchUrl = "https://macrumors.com"
|
||||
|
||||
func testCancel() {
|
||||
guard let folder = getFolderByLoadingInitialContent() else {
|
||||
return
|
||||
}
|
||||
|
||||
let progress = DownloadProgress(numberOfTasks: 0)
|
||||
let _ = expectationForCompletion(of: progress)
|
||||
|
||||
let addNewFeed = try! FeedlyAddNewFeedOperation(account: account,
|
||||
credentials: support.accessToken,
|
||||
url: searchUrl,
|
||||
feedName: nil,
|
||||
searchService: caller,
|
||||
addToCollectionService: caller,
|
||||
syncUnreadIdsService: caller,
|
||||
getStreamContentsService: caller,
|
||||
container: folder,
|
||||
progress: progress,
|
||||
log: support.log)
|
||||
|
||||
// If this expectation is not fulfilled, the operation is not calling `didFinish`.
|
||||
let completionExpectation = expectation(description: "Did Finish")
|
||||
addNewFeed.completionBlock = {
|
||||
completionExpectation.fulfill()
|
||||
}
|
||||
|
||||
OperationQueue.main.addOperation(addNewFeed)
|
||||
|
||||
XCTAssert(progress.numberRemaining > 0)
|
||||
|
||||
addNewFeed.cancel()
|
||||
|
||||
waitForExpectations(timeout: 2)
|
||||
|
||||
XCTAssert(progress.isComplete)
|
||||
}
|
||||
|
||||
func testAddNewFeedSuccess() {
|
||||
guard let folder = getFolderByLoadingInitialContent() else {
|
||||
return
|
||||
}
|
||||
|
||||
let progress = DownloadProgress(numberOfTasks: 0)
|
||||
let _ = expectationForCompletion(of: progress)
|
||||
|
||||
let subdirectory = "feedly-add-new-feed"
|
||||
let searchUrl = self.searchUrl
|
||||
let provider = MockResponseProvider(findingMocksIn: subdirectory)
|
||||
provider.searchQueryHandler = { query in
|
||||
XCTAssertEqual(query, searchUrl)
|
||||
}
|
||||
|
||||
transport.mockResponseFileUrlProvider = provider
|
||||
|
||||
let addNewFeed = try! FeedlyAddNewFeedOperation(account: account,
|
||||
credentials: support.accessToken,
|
||||
url: searchUrl,
|
||||
feedName: nil,
|
||||
searchService: caller,
|
||||
addToCollectionService: caller,
|
||||
syncUnreadIdsService: caller,
|
||||
getStreamContentsService: caller,
|
||||
container: folder,
|
||||
progress: progress,
|
||||
log: support.log)
|
||||
|
||||
// If this expectation is not fulfilled, the operation is not calling `didFinish`.
|
||||
let completionExpectation = expectation(description: "Did Finish")
|
||||
addNewFeed.completionBlock = {
|
||||
completionExpectation.fulfill()
|
||||
}
|
||||
|
||||
OperationQueue.main.addOperation(addNewFeed)
|
||||
|
||||
XCTAssert(progress.numberRemaining > 0)
|
||||
|
||||
waitForExpectations(timeout: 2)
|
||||
|
||||
XCTAssert(progress.isComplete)
|
||||
|
||||
support.checkArticles(in: account, againstItemsInStreamInJSONNamed: "feedStream", subdirectory: subdirectory)
|
||||
support.checkUnreadStatuses(in: account, againstIdsInStreamInJSONNamed: "unreadIds", subdirectory: subdirectory)
|
||||
}
|
||||
|
||||
class TestFeedlyAddFeedToCollectionService: FeedlyAddFeedToCollectionService {
|
||||
var mockResult: Result<[FeedlyFeed], Error>?
|
||||
var addFeedExpectation: XCTestExpectation?
|
||||
var parameterTester: ((FeedlyFeedResourceId, String?, String) -> ())?
|
||||
|
||||
func addFeed(with feedId: FeedlyFeedResourceId, title: String?, toCollectionWith collectionId: String, completionHandler: @escaping (Result<[FeedlyFeed], Error>) -> ()) {
|
||||
guard let result = mockResult else {
|
||||
XCTFail("Missing mock result. Test may time out because the completion will not be called.")
|
||||
return
|
||||
}
|
||||
parameterTester?(feedId, title, collectionId)
|
||||
DispatchQueue.main.async {
|
||||
completionHandler(result)
|
||||
self.addFeedExpectation?.fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testAddNewFeedFailure() {
|
||||
guard let folder = getFolderByLoadingInitialContent() else {
|
||||
return
|
||||
}
|
||||
|
||||
let progress = DownloadProgress(numberOfTasks: 0)
|
||||
let _ = expectationForCompletion(of: progress)
|
||||
|
||||
let subdirectory = "feedly-add-new-feed"
|
||||
let searchUrl = self.searchUrl
|
||||
let feedName = "MacRumours with a \"u\" because I am Australian"
|
||||
let provider = MockResponseProvider(findingMocksIn: subdirectory)
|
||||
provider.searchQueryHandler = { query in
|
||||
XCTAssertEqual(query, searchUrl)
|
||||
}
|
||||
|
||||
transport.mockResponseFileUrlProvider = provider
|
||||
|
||||
let service = TestFeedlyAddFeedToCollectionService()
|
||||
service.mockResult = .failure(URLError(.timedOut))
|
||||
service.addFeedExpectation = expectation(description: "Add New Feed Called")
|
||||
service.parameterTester = { feedResource, title, collectionId in
|
||||
XCTAssertEqual(feedResource.id, "feed/http://feeds.macrumors.com/MacRumors-All")
|
||||
XCTAssertEqual(title, feedName)
|
||||
XCTAssertEqual(collectionId, folder.externalID)
|
||||
}
|
||||
|
||||
let addNewFeed = try! FeedlyAddNewFeedOperation(account: account,
|
||||
credentials: support.accessToken,
|
||||
url: searchUrl,
|
||||
feedName: feedName,
|
||||
searchService: caller,
|
||||
addToCollectionService: service,
|
||||
syncUnreadIdsService: caller,
|
||||
getStreamContentsService: caller,
|
||||
container: folder,
|
||||
progress: progress,
|
||||
log: support.log)
|
||||
|
||||
// If this expectation is not fulfilled, the operation is not calling `didFinish`.
|
||||
let completionExpectation = expectation(description: "Did Finish")
|
||||
addNewFeed.completionBlock = {
|
||||
completionExpectation.fulfill()
|
||||
}
|
||||
|
||||
OperationQueue.main.addOperation(addNewFeed)
|
||||
|
||||
XCTAssert(progress.numberRemaining > 0)
|
||||
|
||||
waitForExpectations(timeout: 2)
|
||||
|
||||
XCTAssert(progress.isComplete)
|
||||
|
||||
XCTAssertEqual(folder.topLevelWebFeeds.count, 0)
|
||||
}
|
||||
}
|
||||
|
||||
private class InitialMockResponseProvider: TestTransportMockResponseProviding {
|
||||
|
||||
let subdirectory: String
|
||||
|
||||
init(findingMocksIn subdirectory: String) {
|
||||
self.subdirectory = subdirectory
|
||||
}
|
||||
|
||||
func mockResponseFileUrl(for components: URLComponents) -> URL? {
|
||||
let bundle = Bundle(for: type(of: self))
|
||||
|
||||
// When we get a request for the initial collections content, use these results.
|
||||
if components.path.contains("/v3/collections") {
|
||||
return bundle.url(forResource: "emptyCollections", withExtension: "json", subdirectory: subdirectory)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class MockResponseProvider: TestTransportMockResponseProviding {
|
||||
|
||||
let subdirectory: String
|
||||
|
||||
init(findingMocksIn subdirectory: String) {
|
||||
self.subdirectory = subdirectory
|
||||
}
|
||||
|
||||
var searchQueryHandler: ((String) -> ())?
|
||||
|
||||
func mockResponseFileUrl(for components: URLComponents) -> URL? {
|
||||
let bundle = Bundle(for: type(of: self))
|
||||
|
||||
let queryItems = components.queryItems ?? []
|
||||
let query = queryItems.first(where: { $0.name.contains("query") })?.value
|
||||
|
||||
// When we get the search request, use these results.
|
||||
if components.path.contains("search/feeds") {
|
||||
if let query = query {
|
||||
searchQueryHandler?(query)
|
||||
} else {
|
||||
XCTFail("`query` missing from URL query items in search request: \(components)")
|
||||
}
|
||||
return bundle.url(forResource: "searchResults", withExtension: "json", subdirectory: subdirectory)
|
||||
}
|
||||
|
||||
// When we get a request to add a feed, use these results.
|
||||
if components.path.contains("/v3/collections") && components.path.contains("/feeds") {
|
||||
return bundle.url(forResource: "putFeed", withExtension: "json", subdirectory: subdirectory)
|
||||
}
|
||||
|
||||
// When we get a request for the initial collections content, use these results.
|
||||
if components.path.contains("/v3/collections") {
|
||||
return bundle.url(forResource: "collections", withExtension: "json", subdirectory: subdirectory)
|
||||
}
|
||||
|
||||
let continuation = queryItems.first(where: { $0.name.contains("continuation") })?.value
|
||||
|
||||
// When we get a request for unread article ids, use these results.
|
||||
if components.path.contains("streams/ids") {
|
||||
|
||||
// if there is a continuation, return the page for it
|
||||
if let continuation = continuation, let data = continuation.data(using: .utf8) {
|
||||
let base64 = data.base64EncodedString() // at least base64 can be used as a path component.
|
||||
return bundle.url(forResource: "unreadIds@\(base64)", withExtension: "json", subdirectory: subdirectory)
|
||||
|
||||
} else {
|
||||
// return first page
|
||||
return bundle.url(forResource: "unreadIds", withExtension: "json", subdirectory: subdirectory)
|
||||
}
|
||||
}
|
||||
|
||||
// When we get a request for the contents of the feed stream, use these results.
|
||||
if components.path.contains("streams/contents") {
|
||||
|
||||
// if there is a continuation, return the page for it
|
||||
if let continuation = continuation, let data = continuation.data(using: .utf8) {
|
||||
let base64 = data.base64EncodedString() // at least base64 can be used as a path component.
|
||||
return bundle.url(forResource: "feedStream@\(base64)", withExtension: "json", subdirectory: subdirectory)
|
||||
|
||||
} else {
|
||||
// return first page
|
||||
return bundle.url(forResource: "feedStream", withExtension: "json", subdirectory: subdirectory)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
[{"customizable":true,"feeds":[{"feedId":"feed/http://feeds.macrumors.com/MacRumors-All","id":"feed/http://feeds.macrumors.com/MacRumors-All","title":"MacRumors: Mac News and Rumors - All Stories","updated":1575325551366,"velocity":54.4,"subscribers":3,"website":"https://www.macrumors.com","language":"en","description":"Apple, iPhone, iPad, Mac News and Rumors"}],"label":"Mac","created":1575325095480,"enterprise":false,"numFeeds":1,"id":"user/c665fbfb-36e1-485a-918b-90d91f2ebd01/category/da60a29f-94ba-4856-b64f-2830d9859ee8"}]
|
@ -0,0 +1 @@
|
||||
[{"customizable":true,"feeds":[],"label":"Mac","created":1575325095480,"enterprise":false,"numFeeds":0,"id":"user/c665fbfb-36e1-485a-918b-90d91f2ebd01/category/da60a29f-94ba-4856-b64f-2830d9859ee8"}]
|
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
[{"feedId":"feed/http://feeds.macrumors.com/MacRumors-All","id":"feed/http://feeds.macrumors.com/MacRumors-All","title":"MacRumors: Mac News and Rumors - All Stories","updated":1575318341631,"velocity":54.4,"subscribers":2,"website":"https://www.macrumors.com","language":"en","description":"Apple, iPhone, iPad, Mac News and Rumors"}]
|
@ -0,0 +1 @@
|
||||
{"results":[{"feedId":"feed/http://feeds.macrumors.com/MacRumors-All","score":1.1779602,"lastUpdated":1535409540000,"coverage":0.0,"averageReadTime":0.0,"coverageScore":0.0,"tagCounts":{"ios":1},"totalTagCount":1,"scheme":"u:b:o","id":"feed/http://feeds.macrumors.com/MacRumors-All","title":"MacRumors: Mac News and Rumors - All Stories","updated":1535409540000,"velocity":54.4,"subscribers":3,"website":"https://www.macrumors.com","language":"en","description":"Apple, iPhone, iPad, Mac News and Rumors","deliciousTags":["ios"]}],"queryType":"url","related":["ios"],"scheme":"u:b:o"}
|
@ -0,0 +1,15 @@
|
||||
{
|
||||
"ids": [
|
||||
"i5dK0N4LYkCdW27N2hxMjfOjdU7G+cHFwqWTCuim9HU=_16ec8b84b06:105f8:40944486",
|
||||
"i5dK0N4LYkCdW27N2hxMjfOjdU7G+cHFwqWTCuim9HU=_16ec84a47ff:10035:40944486",
|
||||
"i5dK0N4LYkCdW27N2hxMjfOjdU7G+cHFwqWTCuim9HU=_16ec81358b5:fd6a:40944486",
|
||||
"i5dK0N4LYkCdW27N2hxMjfOjdU7G+cHFwqWTCuim9HU=_16ec7dc2863:f9eb:40944486",
|
||||
"i5dK0N4LYkCdW27N2hxMjfOjdU7G+cHFwqWTCuim9HU=_16ec7a41b17:f62e:40944486",
|
||||
"i5dK0N4LYkCdW27N2hxMjfOjdU7G+cHFwqWTCuim9HU=_16ec76d1e3f:ee16:40944486",
|
||||
"i5dK0N4LYkCdW27N2hxMjfOjdU7G+cHFwqWTCuim9HU=_16ec76d1e3f:ee15:40944486",
|
||||
"i5dK0N4LYkCdW27N2hxMjfOjdU7G+cHFwqWTCuim9HU=_16ec735cb51:eb40:40944486",
|
||||
"i5dK0N4LYkCdW27N2hxMjfOjdU7G+cHFwqWTCuim9HU=_16ec6fecd41:e87d:40944486",
|
||||
"i5dK0N4LYkCdW27N2hxMjfOjdU7G+cHFwqWTCuim9HU=_16ec6fecd41:e87c:40944486",
|
||||
"i5dK0N4LYkCdW27N2hxMjfOjdU7G+cHFwqWTCuim9HU=_16ec6c7d2b2:e5c8:40944486"
|
||||
]
|
||||
}
|
@ -61,6 +61,13 @@ struct FeedlyCategoryResourceId: FeedlyResourceId {
|
||||
let id = "user/\(userId)/category/global.all"
|
||||
return FeedlyCategoryResourceId(id: id)
|
||||
}
|
||||
|
||||
/// All articles from all the feeds the user loves most.
|
||||
static func mustRead(for userId: String) -> FeedlyCategoryResourceId {
|
||||
// https://developer.feedly.com/cloud/#global-resource-ids
|
||||
let id = "user/\(userId)/category/global.must"
|
||||
return FeedlyCategoryResourceId(id: id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user