From 6675f348487875b4d8ebe81b448b9aa133acaa64 Mon Sep 17 00:00:00 2001 From: Vladyslav Anokhin Date: Thu, 31 Jan 2019 14:44:28 +0200 Subject: [PATCH] Moved wrapper processing from item controller to processing controller --- sources/VVPSDK.swift | 6 +- .../Controllers/VRMItemController.swift | 12 +--- .../Controllers/VRMItemControllerTest.swift | 43 ++----------- .../Controllers/VRMProcessingController.swift | 22 ++++++- .../VRMProcessingControllerTest.swift | 61 ++++++++++++++++--- 5 files changed, 80 insertions(+), 64 deletions(-) diff --git a/sources/VVPSDK.swift b/sources/VVPSDK.swift index ed79163..7e15ed5 100644 --- a/sources/VVPSDK.swift +++ b/sources/VVPSDK.swift @@ -410,14 +410,14 @@ public struct VVPSDK { func setupVRMWithNewCore() { let maxRedirectCount = player.model.adSettings.maxVASTWrapperRedirectCount let prefetchOffset = player.model.adSettings.prefetchingOffset - let maxAdSearchTime: TimeInterval = 9 + let maxAdSearchTime = player.model.adSettings.maxSearchTime let createRequest: (URL) -> (URLRequest) = { .init(url: $0, timeoutInterval: hardTimeout) } let adStartProcessing = StartAdProcessingController(prefetchOffset: prefetchOffset, dispatch: dispatcher) let startGroupProcessing = StartVRMGroupProcessingController(dispatch: dispatcher) let finishGroupProcessing = FinishVRMGroupProcessingController(dispatch: dispatcher) - let itemController = VRMItemController(maxRedirectCount: maxRedirectCount, dispatch: dispatcher) + let itemController = VRMItemController(dispatch: dispatcher) let itemFetchController = FetchVRMItemController(dispatch: dispatcher) { url in self.ephemeralSession.dataFuture(with: createRequest(url)) .map(Network.Parse.successResponseData) @@ -431,7 +431,7 @@ public struct VVPSDK { groupsMapper: mapGroups) { url in self.vrmProvider.requestAds(with: createRequest(url)) } - let processingController = VRMProcessingController(dispatch: dispatcher) + let processingController = VRMProcessingController(maxRedirectCount: maxRedirectCount, dispatch: dispatcher) let createSoftTimeoutTimer = { Timer(duration: softTimeout){ dispatcher(PlayerCore.VRMCore.softTimeoutReached()) } } let createHardTimeoutTimer = { Timer(duration: hardTimeout){ dispatcher(PlayerCore.VRMCore.hardTimeoutReached()) } } let timeoutController = VRMTimeoutController(softTimeoutTimerFactory: createSoftTimeoutTimer, diff --git a/sources/advertisements/VRM New Core/Controllers/VRMItemController.swift b/sources/advertisements/VRM New Core/Controllers/VRMItemController.swift index d58cb7a..ca68c65 100644 --- a/sources/advertisements/VRM New Core/Controllers/VRMItemController.swift +++ b/sources/advertisements/VRM New Core/Controllers/VRMItemController.swift @@ -6,14 +6,12 @@ import PlayerCore final class VRMItemController { - let maxRedirectCount: Int let dispatch: (PlayerCore.Action) -> Void private var startedCandidates = Set() private var wrapperError = Set() - init(maxRedirectCount: Int, dispatch: @escaping (PlayerCore.Action) -> Void ) { - self.maxRedirectCount = maxRedirectCount + init(dispatch: @escaping (PlayerCore.Action) -> Void ) { self.dispatch = dispatch } @@ -29,14 +27,6 @@ final class VRMItemController { } scheduledItems.forEach { originalItem, queue in - guard queue.count < maxRedirectCount else { - if wrapperError.contains(originalItem) == false { - wrapperError.insert(originalItem) - dispatch(VRMCore.tooManyIndirections(item: originalItem)) - } - return - } - queue.subtracting(startedCandidates) .forEach { candidate in startedCandidates.insert(candidate) diff --git a/sources/advertisements/VRM New Core/Controllers/VRMItemControllerTest.swift b/sources/advertisements/VRM New Core/Controllers/VRMItemControllerTest.swift index 320448d..c55aaf3 100644 --- a/sources/advertisements/VRM New Core/Controllers/VRMItemControllerTest.swift +++ b/sources/advertisements/VRM New Core/Controllers/VRMItemControllerTest.swift @@ -20,7 +20,6 @@ class VRMItemControllerTest: XCTestCase { $0.url == $1.url && $0.originalItem == $1.originalItem } - let maxRedirectCount = 3 let url = URL(string: "http://test.com")! let vastXML = "VAST String" var vastItem: VRMCore.Item! @@ -50,7 +49,7 @@ class VRMItemControllerTest: XCTestCase { func testMaxAdSearchTimeout() { let dispatch = recorder.hook("testMaxAdSearchTimeout", cmp: fetchActionComparator.compare) - sut = VRMItemController(maxRedirectCount: maxRedirectCount, dispatch: dispatch) + sut = VRMItemController(dispatch: dispatch) recorder.record { sut.process(with: [urlItem: Set([.init(source: urlItem.source)])], isMaxAdSearchTimeReached: true) @@ -62,7 +61,7 @@ class VRMItemControllerTest: XCTestCase { func testStartItemsFetching() { let dispatch = recorder.hook("compareFetchActions", cmp: fetchActionComparator.compare) - sut = VRMItemController(maxRedirectCount: maxRedirectCount, dispatch: dispatch) + sut = VRMItemController(dispatch: dispatch) recorder.record { sut.process(with: [urlItem: Set([.init(source: urlItem.source)])], isMaxAdSearchTimeReached: false) @@ -76,7 +75,7 @@ class VRMItemControllerTest: XCTestCase { func testStartItemsParsing() { let dispatch = recorder.hook("testStartItemsParsing", cmp: parseActionComparator.compare) - sut = VRMItemController(maxRedirectCount: maxRedirectCount, dispatch: dispatch) + sut = VRMItemController(dispatch: dispatch) recorder.record { sut.process(with: [vastItem: Set([.init(source: vastItem.source)])], isMaxAdSearchTimeReached: false) @@ -90,7 +89,7 @@ class VRMItemControllerTest: XCTestCase { func testDoubleDispatch() { let dispatch = recorder.hook("testDoubleDispatch", cmp: parseActionComparator.compare) - sut = VRMItemController(maxRedirectCount: maxRedirectCount, dispatch: dispatch) + sut = VRMItemController(dispatch: dispatch) recorder.record { let scheduledQueue: [VRMCore.Item: Set] = [vastItem: Set(arrayLiteral: .init(source: vastItem.source))] @@ -107,7 +106,7 @@ class VRMItemControllerTest: XCTestCase { var compare = parseActionComparator.compare let dispatch = recorder.hook("testProcessWrapper", cmp: { compare($0,$1) }) - sut = VRMItemController(maxRedirectCount: maxRedirectCount, dispatch: dispatch) + sut = VRMItemController(dispatch: dispatch) let first = ScheduledVRMItems.Candidate(source: vastItem.source) let second = ScheduledVRMItems.Candidate(source: .url(url)) @@ -129,36 +128,4 @@ class VRMItemControllerTest: XCTestCase { sut.dispatch(VRMCore.startItemFetch(originalItem: vastItem, url: url)) } } - - func testMaxRedirectAndNextGroupProcess() { - var compare = wrapperErrorActionComparator.compare - let dispatch = recorder.hook("testMaxRedirect", cmp: { compare($0,$1) }) - - sut = VRMItemController(maxRedirectCount: maxRedirectCount, dispatch: dispatch) - - let queueWithTooManyWrappers = Set([.init(source: urlItem.source), - .init(source: .url(URL(string:"http://test1.com")!)), - .init(source: .url(URL(string:"http://test2.com")!))]) - recorder.record { - sut.process(with: [urlItem: queueWithTooManyWrappers], isMaxAdSearchTimeReached: false) - sut.process(with: [urlItem: queueWithTooManyWrappers], isMaxAdSearchTimeReached: false) - } - - recorder.verify { - sut.dispatch(VRMCore.tooManyIndirections(item: urlItem)) - } - - let correctQueue = Set([.init(source: vastItem.source)]) - compare = parseActionComparator.compare - - recorder.record { - sut.process(with: [urlItem: queueWithTooManyWrappers, - vastItem: correctQueue], - isMaxAdSearchTimeReached: false) - } - - recorder.verify { - sut.dispatch(VRMCore.startItemParsing(originalItem: vastItem, vastXML: vastXML)) - } - } } diff --git a/sources/advertisements/VRM New Core/Controllers/VRMProcessingController.swift b/sources/advertisements/VRM New Core/Controllers/VRMProcessingController.swift index c91eb25..4e2713e 100644 --- a/sources/advertisements/VRM New Core/Controllers/VRMProcessingController.swift +++ b/sources/advertisements/VRM New Core/Controllers/VRMProcessingController.swift @@ -6,21 +6,26 @@ import PlayerCore final class VRMProcessingController { + let maxRedirectCount: Int let dispatch: (PlayerCore.Action) -> Void + private var dispatchedResults = Set() - init(dispatch: @escaping (PlayerCore.Action) -> Void) { + init(maxRedirectCount: Int,dispatch: @escaping (PlayerCore.Action) -> Void) { + self.maxRedirectCount = maxRedirectCount self.dispatch = dispatch } func process(with state: PlayerCore.State) { process(parsingResultQueue: state.vrmParsingResult.parsedVASTs, + scheduledVRMItems: state.vrmScheduledItems.items, currentGroup: state.vrmCurrentGroup.currentGroup, timeout: state.vrmProcessingTimeout, isMaxAdSearchTimeoutReached: state.vrmMaxAdSearchTimeout.isReached) } func process(parsingResultQueue: [VRMCore.Item: VRMParsingResult.Result], + scheduledVRMItems: [VRMCore.Item: Set], currentGroup: VRMCore.Group?, timeout: VRMProcessingTimeout, isMaxAdSearchTimeoutReached: Bool) { @@ -33,12 +38,23 @@ final class VRMProcessingController { dispatchedResults.contains(result) == false }.forEach { item, result in - if currentGroup == nil || currentGroup?.items.contains(item) == false || timeout == .hard { + if currentGroup == nil || + currentGroup?.items.contains(item) == false || + timeout == .hard { dispatch(VRMCore.timeoutError(item: item)) } else if case .inline(let vast) = result.vastModel { dispatch(VRMCore.selectInlineVAST(item: item, inlineVAST: vast)) } else if case .wrapper(let wrapper) = result.vastModel { - dispatch(VRMCore.unwrapItem(item: item, url: wrapper.tagURL)) + guard let count = scheduledVRMItems[item]?.count else { + assertionFailure("try to unwrap item, which wasn't started") + return + } + + if (count + 1) < maxRedirectCount { + dispatch(VRMCore.unwrapItem(item: item, url: wrapper.tagURL)) + } else { + dispatch(VRMCore.tooManyIndirections(item: item)) + } } dispatchedResults.insert(result) diff --git a/sources/advertisements/VRM New Core/Controllers/VRMProcessingControllerTest.swift b/sources/advertisements/VRM New Core/Controllers/VRMProcessingControllerTest.swift index 66ff380..ef19ecf 100644 --- a/sources/advertisements/VRM New Core/Controllers/VRMProcessingControllerTest.swift +++ b/sources/advertisements/VRM New Core/Controllers/VRMProcessingControllerTest.swift @@ -7,7 +7,9 @@ import XCTest class VRMProcessingControllerTest: XCTestCase { + let maxRedirectCount = 3 let recorder = Recorder() + let timeoutActionComparator = ActionComparator { $0.item == $1.item } @@ -17,6 +19,9 @@ class VRMProcessingControllerTest: XCTestCase { let unwrapItemActionComparator = ActionComparator { $0.item == $1.item && $0.url == $1.url } + let wrapperErrorActionComparator = ActionComparator { + $0.item == $1.item + } let wrapperUrl = URL(string: "http://test.com")! var wrapper: VRMCore.VASTModel! @@ -55,15 +60,18 @@ class VRMProcessingControllerTest: XCTestCase { } func testTimeoutItemAndDoublDispatch() { - let sut = VRMProcessingController(dispatch: recorder.hook("testTimeoutItem", cmp: timeoutActionComparator.compare)) + let sut = VRMProcessingController(maxRedirectCount: maxRedirectCount, + dispatch: recorder.hook("testTimeoutItem", cmp: timeoutActionComparator.compare)) recorder.record { let result = VRMParsingResult.Result(vastModel: inline) sut.process(parsingResultQueue: [vastItem: result], + scheduledVRMItems: [:], currentGroup: nil, timeout: .none, isMaxAdSearchTimeoutReached: false) sut.process(parsingResultQueue: [vastItem: result], + scheduledVRMItems: [:], currentGroup: nil, timeout: .none, isMaxAdSearchTimeoutReached: false) @@ -77,10 +85,12 @@ class VRMProcessingControllerTest: XCTestCase { recorder.record { let result = VRMParsingResult.Result(vastModel: inline) sut.process(parsingResultQueue: [vastItem: result], + scheduledVRMItems: [:], currentGroup: group, timeout: .hard, isMaxAdSearchTimeoutReached: false) sut.process(parsingResultQueue: [vastItem: result], + scheduledVRMItems: [:], currentGroup: group, timeout: .hard, isMaxAdSearchTimeoutReached: false) @@ -92,11 +102,13 @@ class VRMProcessingControllerTest: XCTestCase { } func testItemFromAnotherGroup() { - let sut = VRMProcessingController(dispatch: recorder.hook("testItemFromAnotherGroup", cmp: timeoutActionComparator.compare)) + let sut = VRMProcessingController(maxRedirectCount: maxRedirectCount, + dispatch: recorder.hook("testItemFromAnotherGroup", cmp: timeoutActionComparator.compare)) let group = VRMCore.Group(items: [urlItem]) recorder.record { sut.process(parsingResultQueue: [vastItem: .init(vastModel: inline)], + scheduledVRMItems: [:], currentGroup: group, timeout: .none, isMaxAdSearchTimeoutReached: false) @@ -108,12 +120,13 @@ class VRMProcessingControllerTest: XCTestCase { } func testSelectInlineModel() { - let sut = VRMProcessingController(dispatch: recorder.hook("testSelectInlineModel", - cmp: selectInlineAdActionComparator.compare)) + let sut = VRMProcessingController(maxRedirectCount: maxRedirectCount, + dispatch: recorder.hook("testSelectInlineModel", cmp: selectInlineAdActionComparator.compare)) let group = VRMCore.Group(items: [urlItem]) recorder.record { sut.process(parsingResultQueue: [urlItem: .init(vastModel: inline)], + scheduledVRMItems: [:], currentGroup: group, timeout: .soft, isMaxAdSearchTimeoutReached: false) @@ -125,12 +138,12 @@ class VRMProcessingControllerTest: XCTestCase { } func testWrapperModel() { - let sut = VRMProcessingController(dispatch: recorder.hook("testWrapperModel", - cmp: unwrapItemActionComparator.compare)) - + let sut = VRMProcessingController(maxRedirectCount: maxRedirectCount, + dispatch: recorder.hook("testWrapperModel", cmp: unwrapItemActionComparator.compare)) let group = VRMCore.Group(items: [urlItem]) recorder.record { sut.process(parsingResultQueue: [urlItem: .init(vastModel: wrapper)], + scheduledVRMItems: [urlItem: Set()], currentGroup: group, timeout: .none, isMaxAdSearchTimeoutReached: false) @@ -142,12 +155,13 @@ class VRMProcessingControllerTest: XCTestCase { } func testMaxAdSearchTime() { - let sut = VRMProcessingController(dispatch: recorder.hook("testMaxAdSearchTime", - cmp: unwrapItemActionComparator.compare)) + let sut = VRMProcessingController(maxRedirectCount: maxRedirectCount, + dispatch: recorder.hook("testMaxAdSearchTime", cmp: unwrapItemActionComparator.compare)) let group = VRMCore.Group(items: [urlItem]) recorder.record { sut.process(parsingResultQueue: [urlItem: .init(vastModel: wrapper)], + scheduledVRMItems: [:], currentGroup: group, timeout: .none, isMaxAdSearchTimeoutReached: true) @@ -155,4 +169,33 @@ class VRMProcessingControllerTest: XCTestCase { recorder.verify {} } + + func testMaxRedirectCount() { + let queueWithTooManyWrappers = Set([.init(source: urlItem.source), + .init(source: .url(URL(string:"http://test1.com")!))]) + let parsingQueue: [VRMCore.Item: VRMParsingResult.Result] = [urlItem: .init(vastModel: wrapper)] + + let hook = recorder.hook("testMaxRedirectCount", cmp: wrapperErrorActionComparator.compare) + let sut = VRMProcessingController(maxRedirectCount: maxRedirectCount, dispatch: hook) + let group = VRMCore.Group(items: [urlItem]) + + + recorder.record { + sut.process(parsingResultQueue:parsingQueue, + scheduledVRMItems: [urlItem: queueWithTooManyWrappers], + currentGroup: group, + timeout: .none, + isMaxAdSearchTimeoutReached: false) + + sut.process(parsingResultQueue: parsingQueue, + scheduledVRMItems: [urlItem: queueWithTooManyWrappers], + currentGroup: group, + timeout: .none, + isMaxAdSearchTimeoutReached: false) + } + + recorder.verify { + sut.dispatch(VRMCore.tooManyIndirections(item: urlItem)) + } + } }