From d719f48a85a347b3831c99d9c7075d7dae55bc46 Mon Sep 17 00:00:00 2001 From: Andrey Moskvin Date: Fri, 14 Dec 2018 19:12:51 +0200 Subject: [PATCH 1/4] WIP: cpm implementation --- .../TrackingPixelsGenerator.swift | 134 ++++++++++++++++-- .../TrackingPixelsReporter.swift | 48 +++++-- 2 files changed, 153 insertions(+), 29 deletions(-) diff --git a/sources/metrics/tracking pixels/TrackingPixelsGenerator.swift b/sources/metrics/tracking pixels/TrackingPixelsGenerator.swift index 7778534..dbdfb1d 100644 --- a/sources/metrics/tracking pixels/TrackingPixelsGenerator.swift +++ b/sources/metrics/tracking pixels/TrackingPixelsGenerator.swift @@ -25,7 +25,9 @@ extension TrackingPixels.Generator { vcid: String? = nil, mpid: String? = nil, cb: String, - m_fwsitesection: String? = nil) -> URLComponents + m_fwsitesection: String? = nil, + bckt: String? = nil, + expn: String? = nil) -> URLComponents { var queryItems = [URLQueryItem]() @@ -44,6 +46,8 @@ extension TrackingPixels.Generator { if let mpid = mpid { queryItems.append(URLQueryItem(name: "mpid", value: mpid)) } queryItems.append(URLQueryItem(name: "cb", value: cb)) if let m_fwsitesection = m_fwsitesection { queryItems.append(URLQueryItem(name: "m.fwsitesection", value: m_fwsitesection)) } + if let bckt = bckt { queryItems.append(URLQueryItem(name: "bckt", value: bckt)) } + if let expn = expn { queryItems.append(URLQueryItem(name: "expn", value: expn)) } var components = URLComponents() components.path = "trk/context-started.gif" @@ -71,7 +75,9 @@ extension TrackingPixels.Generator { vcid: String? = nil, mpid: String? = nil, cb: String, - m_fwsitesection: String? = nil) -> URLComponents + m_fwsitesection: String? = nil, + bckt: String? = nil, + expn: String? = nil) -> URLComponents { var queryItems = [URLQueryItem]() @@ -94,6 +100,8 @@ extension TrackingPixels.Generator { if let mpid = mpid { queryItems.append(URLQueryItem(name: "mpid", value: mpid)) } queryItems.append(URLQueryItem(name: "cb", value: cb)) if let m_fwsitesection = m_fwsitesection { queryItems.append(URLQueryItem(name: "m.fwsitesection", value: m_fwsitesection)) } + if let bckt = bckt { queryItems.append(URLQueryItem(name: "bckt", value: bckt)) } + if let expn = expn { queryItems.append(URLQueryItem(name: "expn", value: expn)) } var components = URLComponents() components.path = "trk/video-play.gif" @@ -168,7 +176,9 @@ extension TrackingPixels.Generator { vcid: String? = nil, mpid: String? = nil, cb: String, - m_fwsitesection: String? = nil) -> URLComponents + m_fwsitesection: String? = nil, + bckt: String? = nil, + expn: String? = nil) -> URLComponents { var queryItems = [URLQueryItem]() @@ -190,6 +200,8 @@ extension TrackingPixels.Generator { if let mpid = mpid { queryItems.append(URLQueryItem(name: "mpid", value: mpid)) } queryItems.append(URLQueryItem(name: "cb", value: cb)) if let m_fwsitesection = m_fwsitesection { queryItems.append(URLQueryItem(name: "m.fwsitesection", value: m_fwsitesection)) } + if let bckt = bckt { queryItems.append(URLQueryItem(name: "bckt", value: bckt)) } + if let expn = expn { queryItems.append(URLQueryItem(name: "expn", value: expn)) } var components = URLComponents() components.path = "trk/video-quartile.gif" @@ -306,7 +318,11 @@ extension TrackingPixels.Generator { cb: String, s: String? = nil, w: String? = nil, - m_fwsitesection: String? = nil) -> URLComponents + m_fwsitesection: String? = nil, + poid: String? = nil, + adseq: String? = nil, + bckt: String? = nil, + expn: String? = nil) -> URLComponents { var queryItems = [URLQueryItem]() @@ -328,6 +344,10 @@ extension TrackingPixels.Generator { if let s = s { queryItems.append(URLQueryItem(name: "s", value: s)) } if let w = w { queryItems.append(URLQueryItem(name: "w", value: w)) } if let m_fwsitesection = m_fwsitesection { queryItems.append(URLQueryItem(name: "m.fwsitesection", value: m_fwsitesection)) } + if let poid = poid { queryItems.append(URLQueryItem(name: "poid", value: poid)) } + if let adseq = adseq { queryItems.append(URLQueryItem(name: "adseq", value: adseq)) } + if let bckt = bckt { queryItems.append(URLQueryItem(name: "bckt", value: bckt)) } + if let expn = expn { queryItems.append(URLQueryItem(name: "expn", value: expn)) } var components = URLComponents() components.path = "trk/slot-opp.gif" @@ -352,7 +372,9 @@ extension TrackingPixels.Generator { r: String, vvuid: String? = nil, cb: String, - m_fwsitesection: String? = nil) -> URLComponents + m_fwsitesection: String? = nil, + bckt: String? = nil, + expn: String? = nil) -> URLComponents { var queryItems = [URLQueryItem]() @@ -372,6 +394,8 @@ extension TrackingPixels.Generator { if let vvuid = vvuid { queryItems.append(URLQueryItem(name: "vvuid", value: vvuid)) } queryItems.append(URLQueryItem(name: "cb", value: cb)) if let m_fwsitesection = m_fwsitesection { queryItems.append(URLQueryItem(name: "m.fwsitesection", value: m_fwsitesection)) } + if let bckt = bckt { queryItems.append(URLQueryItem(name: "bckt", value: bckt)) } + if let expn = expn { queryItems.append(URLQueryItem(name: "expn", value: expn)) } var components = URLComponents() components.path = "trk/ad-request.gif" @@ -391,7 +415,10 @@ extension TrackingPixels.Generator { uuid: String? = nil, vvuid: String? = nil, cb: String, - m_fwsitesection: String? = nil) -> URLComponents + m_fwsitesection: String? = nil, + bckt: String? = nil, + expn: String? = nil, + cpm: String? = nil) -> URLComponents { var queryItems = [URLQueryItem]() @@ -406,6 +433,9 @@ extension TrackingPixels.Generator { if let vvuid = vvuid { queryItems.append(URLQueryItem(name: "vvuid", value: vvuid)) } queryItems.append(URLQueryItem(name: "cb", value: cb)) if let m_fwsitesection = m_fwsitesection { queryItems.append(URLQueryItem(name: "m.fwsitesection", value: m_fwsitesection)) } + if let bckt = bckt { queryItems.append(URLQueryItem(name: "bckt", value: bckt)) } + if let expn = expn { queryItems.append(URLQueryItem(name: "expn", value: expn)) } + if let cpm = cpm { queryItems.append(URLQueryItem(name: "cpm", value: cpm)) } var components = URLComponents() components.path = "ads/ad-request.gif" @@ -436,7 +466,12 @@ extension TrackingPixels.Generator { vvuid: String? = nil, cb: String, aid: String? = nil, - m_fwsitesection: String? = nil) -> URLComponents + m_fwsitesection: String? = nil, + poid: String? = nil, + adseq: String? = nil, + bckt: String? = nil, + expn: String? = nil, + cpm: String? = nil) -> URLComponents { var queryItems = [URLQueryItem]() @@ -462,6 +497,11 @@ extension TrackingPixels.Generator { queryItems.append(URLQueryItem(name: "cb", value: cb)) if let aid = aid { queryItems.append(URLQueryItem(name: "aid", value: aid)) } if let m_fwsitesection = m_fwsitesection { queryItems.append(URLQueryItem(name: "m.fwsitesection", value: m_fwsitesection)) } + if let poid = poid { queryItems.append(URLQueryItem(name: "poid", value: poid)) } + if let adseq = adseq { queryItems.append(URLQueryItem(name: "adseq", value: adseq)) } + if let bckt = bckt { queryItems.append(URLQueryItem(name: "bckt", value: bckt)) } + if let expn = expn { queryItems.append(URLQueryItem(name: "expn", value: expn)) } + if let cpm = cpm { queryItems.append(URLQueryItem(name: "cpm", value: cpm)) } var components = URLComponents() components.path = "trk/ad-issue.gif" @@ -488,7 +528,12 @@ extension TrackingPixels.Generator { r: String, cb: String, al: String? = nil, - m_fwsitesection: String? = nil) -> URLComponents + m_fwsitesection: String? = nil, + poid: String? = nil, + adseq: String? = nil, + bckt: String? = nil, + expn: String? = nil, + cpm: String? = nil) -> URLComponents { var queryItems = [URLQueryItem]() @@ -510,6 +555,11 @@ extension TrackingPixels.Generator { queryItems.append(URLQueryItem(name: "cb", value: cb)) if let al = al { queryItems.append(URLQueryItem(name: "al", value: al)) } if let m_fwsitesection = m_fwsitesection { queryItems.append(URLQueryItem(name: "m.fwsitesection", value: m_fwsitesection)) } + if let poid = poid { queryItems.append(URLQueryItem(name: "poid", value: poid)) } + if let adseq = adseq { queryItems.append(URLQueryItem(name: "adseq", value: adseq)) } + if let bckt = bckt { queryItems.append(URLQueryItem(name: "bckt", value: bckt)) } + if let expn = expn { queryItems.append(URLQueryItem(name: "expn", value: expn)) } + if let cpm = cpm { queryItems.append(URLQueryItem(name: "cpm", value: cpm)) } var components = URLComponents() components.path = "trk/ad-view-time.gif" @@ -537,7 +587,12 @@ extension TrackingPixels.Generator { aen: String? = nil, vvuid: String? = nil, cb: String, - m_fwsitesection: String? = nil) -> URLComponents + m_fwsitesection: String? = nil, + poid: String? = nil, + adseq: String? = nil, + bckt: String? = nil, + expn: String? = nil, + cpm: String? = nil) -> URLComponents { var queryItems = [URLQueryItem]() @@ -560,6 +615,11 @@ extension TrackingPixels.Generator { if let vvuid = vvuid { queryItems.append(URLQueryItem(name: "vvuid", value: vvuid)) } queryItems.append(URLQueryItem(name: "cb", value: cb)) if let m_fwsitesection = m_fwsitesection { queryItems.append(URLQueryItem(name: "m.fwsitesection", value: m_fwsitesection)) } + if let poid = poid { queryItems.append(URLQueryItem(name: "poid", value: poid)) } + if let adseq = adseq { queryItems.append(URLQueryItem(name: "adseq", value: adseq)) } + if let bckt = bckt { queryItems.append(URLQueryItem(name: "bckt", value: bckt)) } + if let expn = expn { queryItems.append(URLQueryItem(name: "expn", value: expn)) } + if let cpm = cpm { queryItems.append(URLQueryItem(name: "cpm", value: cpm)) } var components = URLComponents() components.path = "trk/ad-engine-request.gif" @@ -591,7 +651,12 @@ extension TrackingPixels.Generator { aen: String? = nil, vvuid: String? = nil, cb: String, - m_fwsitesection: String? = nil) -> URLComponents + m_fwsitesection: String? = nil, + poid: String? = nil, + adseq: String? = nil, + bckt: String? = nil, + expn: String? = nil, + cpm: String? = nil) -> URLComponents { var queryItems = [URLQueryItem]() @@ -618,6 +683,11 @@ extension TrackingPixels.Generator { if let vvuid = vvuid { queryItems.append(URLQueryItem(name: "vvuid", value: vvuid)) } queryItems.append(URLQueryItem(name: "cb", value: cb)) if let m_fwsitesection = m_fwsitesection { queryItems.append(URLQueryItem(name: "m.fwsitesection", value: m_fwsitesection)) } + if let poid = poid { queryItems.append(URLQueryItem(name: "poid", value: poid)) } + if let adseq = adseq { queryItems.append(URLQueryItem(name: "adseq", value: adseq)) } + if let bckt = bckt { queryItems.append(URLQueryItem(name: "bckt", value: bckt)) } + if let expn = expn { queryItems.append(URLQueryItem(name: "expn", value: expn)) } + if let cpm = cpm { queryItems.append(URLQueryItem(name: "cpm", value: cpm)) } var components = URLComponents() components.path = "trk/ad-engine-response.gif" @@ -650,7 +720,12 @@ extension TrackingPixels.Generator { vvuid: String? = nil, cb: String, aid: String? = nil, - m_fwsitesection: String? = nil) -> URLComponents + m_fwsitesection: String? = nil, + poid: String? = nil, + adseq: String? = nil, + bckt: String? = nil, + expn: String? = nil, + cpm: String? = nil) -> URLComponents { var queryItems = [URLQueryItem]() @@ -678,6 +753,11 @@ extension TrackingPixels.Generator { queryItems.append(URLQueryItem(name: "cb", value: cb)) if let aid = aid { queryItems.append(URLQueryItem(name: "aid", value: aid)) } if let m_fwsitesection = m_fwsitesection { queryItems.append(URLQueryItem(name: "m.fwsitesection", value: m_fwsitesection)) } + if let poid = poid { queryItems.append(URLQueryItem(name: "poid", value: poid)) } + if let adseq = adseq { queryItems.append(URLQueryItem(name: "adseq", value: adseq)) } + if let bckt = bckt { queryItems.append(URLQueryItem(name: "bckt", value: bckt)) } + if let expn = expn { queryItems.append(URLQueryItem(name: "expn", value: expn)) } + if let cpm = cpm { queryItems.append(URLQueryItem(name: "cpm", value: cpm)) } var components = URLComponents() components.path = "trk/ad-engine-flow.gif" @@ -702,7 +782,12 @@ extension TrackingPixels.Generator { r: String, vvuid: String? = nil, cb: String, - m_fwsitesection: String? = nil) -> URLComponents + m_fwsitesection: String? = nil, + poid: String? = nil, + adseq: String? = nil, + bckt: String? = nil, + expn: String? = nil, + cpm: String? = nil) -> URLComponents { var queryItems = [URLQueryItem]() @@ -722,6 +807,11 @@ extension TrackingPixels.Generator { if let vvuid = vvuid { queryItems.append(URLQueryItem(name: "vvuid", value: vvuid)) } queryItems.append(URLQueryItem(name: "cb", value: cb)) if let m_fwsitesection = m_fwsitesection { queryItems.append(URLQueryItem(name: "m.fwsitesection", value: m_fwsitesection)) } + if let poid = poid { queryItems.append(URLQueryItem(name: "poid", value: poid)) } + if let adseq = adseq { queryItems.append(URLQueryItem(name: "adseq", value: adseq)) } + if let bckt = bckt { queryItems.append(URLQueryItem(name: "bckt", value: bckt)) } + if let expn = expn { queryItems.append(URLQueryItem(name: "expn", value: expn)) } + if let cpm = cpm { queryItems.append(URLQueryItem(name: "cpm", value: cpm)) } var components = URLComponents() components.path = "trk/mrc-ad-view.gif" @@ -778,7 +868,9 @@ extension TrackingPixels.Generator { vcid: String? = nil, mpid: String? = nil, seq: String? = nil, - m_fwsitesection: String? = nil) -> URLComponents + m_fwsitesection: String? = nil, + bckt: String? = nil, + expn: String? = nil) -> URLComponents { var queryItems = [URLQueryItem]() @@ -800,6 +892,8 @@ extension TrackingPixels.Generator { if let mpid = mpid { queryItems.append(URLQueryItem(name: "mpid", value: mpid)) } if let seq = seq { queryItems.append(URLQueryItem(name: "seq", value: seq)) } if let m_fwsitesection = m_fwsitesection { queryItems.append(URLQueryItem(name: "m.fwsitesection", value: m_fwsitesection)) } + if let bckt = bckt { queryItems.append(URLQueryItem(name: "bckt", value: bckt)) } + if let expn = expn { queryItems.append(URLQueryItem(name: "expn", value: expn)) } var components = URLComponents() components.path = "trk/video-impression.gif" @@ -822,7 +916,9 @@ extension TrackingPixels.Generator { r: String, vvuid: String? = nil, cb: String, - m_fwsitesection: String? = nil) -> URLComponents + m_fwsitesection: String? = nil, + bckt: String? = nil, + expn: String? = nil) -> URLComponents { var queryItems = [URLQueryItem]() @@ -840,6 +936,8 @@ extension TrackingPixels.Generator { if let vvuid = vvuid { queryItems.append(URLQueryItem(name: "vvuid", value: vvuid)) } queryItems.append(URLQueryItem(name: "cb", value: cb)) if let m_fwsitesection = m_fwsitesection { queryItems.append(URLQueryItem(name: "m.fwsitesection", value: m_fwsitesection)) } + if let bckt = bckt { queryItems.append(URLQueryItem(name: "bckt", value: bckt)) } + if let expn = expn { queryItems.append(URLQueryItem(name: "expn", value: expn)) } var components = URLComponents() components.path = "trk/display.gif" @@ -859,7 +957,10 @@ extension TrackingPixels.Generator { uuid: String? = nil, vvuid: String? = nil, cb: String, - m_fwsitesection: String? = nil) -> URLComponents + m_fwsitesection: String? = nil, + bckt: String? = nil, + expn: String? = nil, + cpm: String? = nil) -> URLComponents { var queryItems = [URLQueryItem]() @@ -874,6 +975,9 @@ extension TrackingPixels.Generator { if let vvuid = vvuid { queryItems.append(URLQueryItem(name: "vvuid", value: vvuid)) } queryItems.append(URLQueryItem(name: "cb", value: cb)) if let m_fwsitesection = m_fwsitesection { queryItems.append(URLQueryItem(name: "m.fwsitesection", value: m_fwsitesection)) } + if let bckt = bckt { queryItems.append(URLQueryItem(name: "bckt", value: bckt)) } + if let expn = expn { queryItems.append(URLQueryItem(name: "expn", value: expn)) } + if let cpm = cpm { queryItems.append(URLQueryItem(name: "cpm", value: cpm)) } var components = URLComponents() components.path = "ads/ad-start.gif" diff --git a/sources/metrics/tracking pixels/TrackingPixelsReporter.swift b/sources/metrics/tracking pixels/TrackingPixelsReporter.swift index 726a417..c0aadba 100644 --- a/sources/metrics/tracking pixels/TrackingPixelsReporter.swift +++ b/sources/metrics/tracking pixels/TrackingPixelsReporter.swift @@ -4,6 +4,8 @@ import Foundation enum TrackingPixels {} +typealias CostPerMille = String + extension TrackingPixels { final class Reporter { enum Item { @@ -372,7 +374,8 @@ extension TrackingPixels.Reporter { adId: String?, transactionId: String?, adCurrentTime: Double, - adDuration: Double) { + adDuration: Double, + cpm: CostPerMille) { sendMetric(.tracking( TrackingPixels.Generator.adViewTime( @@ -392,7 +395,8 @@ extension TrackingPixels.Reporter { r: context.referringURL, cb: cachebuster(), al: formatter.string(from: adDuration as NSNumber), - m_fwsitesection: context.siteSection))) + m_fwsitesection: context.siteSection, + cpm: cpm))) } @@ -401,7 +405,8 @@ extension TrackingPixels.Reporter { info: Ad.Metrics.Info, type: Ad.Metrics.PlayType, transactionId: String?, - videoViewUID: String) { + videoViewUID: String, + cpm: CostPerMille) { sendMetric(.tracking( TrackingPixels.Generator.adEngineRequest( app_id: context.applicationID, @@ -422,7 +427,8 @@ extension TrackingPixels.Reporter { aen: info.name, vvuid: videoViewUID, cb: cachebuster(), - m_fwsitesection: context.siteSection))) + m_fwsitesection: context.siteSection, + cpm: cpm))) } func adEngineResponse( @@ -434,7 +440,8 @@ extension TrackingPixels.Reporter { timeout: Int?, fillType: Ad.Metrics.FillType?, transactionId: String?, - videoViewUID: String) { + videoViewUID: String, + cpm: CostPerMille) { sendMetric(.tracking( TrackingPixels.Generator.adEngineResponse( app_id: context.applicationID, @@ -459,7 +466,8 @@ extension TrackingPixels.Reporter { aen: info.name, vvuid: videoViewUID, cb: cachebuster(), - m_fwsitesection: context.siteSection))) + m_fwsitesection: context.siteSection, + cpm: cpm))) } func adEngineIssue( @@ -470,7 +478,8 @@ extension TrackingPixels.Reporter { stage: Ad.Metrics.ExecutionStage?, transactionId: String?, adId: String?, - videoViewUID: String) { + videoViewUID: String, + cpm: CostPerMille) { sendMetric(.tracking( TrackingPixels.Generator.adIssue( app_id: context.applicationID, @@ -494,7 +503,8 @@ extension TrackingPixels.Reporter { vvuid: videoViewUID, cb: cachebuster(), aid: adId, - m_fwsitesection: context.siteSection))) + m_fwsitesection: context.siteSection, + cpm: cpm))) } func adEngineFlow( @@ -507,7 +517,8 @@ extension TrackingPixels.Reporter { autoplay: Bool, transactionId: String?, adId: String?, - videoViewUID: String) { + videoViewUID: String, + cpm: CostPerMille) { sendMetric(.tracking( TrackingPixels.Generator.adEngineFlow( app_id: context.applicationID, @@ -533,7 +544,8 @@ extension TrackingPixels.Reporter { vvuid: videoViewUID, cb: cachebuster(), aid: adId, - m_fwsitesection: context.siteSection))) + m_fwsitesection: context.siteSection, + cpm: cpm))) } func adVRMRequest( @@ -587,7 +599,10 @@ extension TrackingPixels.Reporter { m_fwsitesection: context.siteSection))) } - func adStart(info: Ad.Metrics.Info, videoIndex: Int, videoViewUID: String) { + func adStart(info: Ad.Metrics.Info, + videoIndex: Int, + videoViewUID: String, + cpm: CostPerMille) { sendMetric(.advertisement( TrackingPixels.Generator.adStart( app_id: context.applicationID, @@ -600,10 +615,14 @@ extension TrackingPixels.Reporter { uuid: context.uuid, vvuid: videoViewUID, cb: cachebuster(), - m_fwsitesection: context.siteSection))) + m_fwsitesection: context.siteSection, + cpm: cpm))) } - func adServerRequest(info: Ad.Metrics.Info, videoIndex: Int, videoViewUID: String) { + func adServerRequest(info: Ad.Metrics.Info, + videoIndex: Int, + videoViewUID: String, + cpm: CostPerMille) { sendMetric(.advertisement( TrackingPixels.Generator.adServerRequest( app_id: context.applicationID, @@ -616,7 +635,8 @@ extension TrackingPixels.Reporter { uuid: context.uuid, vvuid: videoViewUID, cb: cachebuster(), - m_fwsitesection: context.siteSection))) + m_fwsitesection: context.siteSection, + cpm: cpm))) } } From efc0735a686a3409e9342c9895dea5124d4f2060 Mon Sep 17 00:00:00 2001 From: Andrey Moskvin Date: Fri, 14 Dec 2018 19:13:38 +0200 Subject: [PATCH 2/4] Project updates --- OathVideoPartnerSDK.xcodeproj/project.pbxproj | 52 +++++++++++++++++++ .../OathVideoPartnerSDK_iOS.xcscheme | 48 ++++++++++------- 2 files changed, 80 insertions(+), 20 deletions(-) diff --git a/OathVideoPartnerSDK.xcodeproj/project.pbxproj b/OathVideoPartnerSDK.xcodeproj/project.pbxproj index d4bf849..1d3acd1 100644 --- a/OathVideoPartnerSDK.xcodeproj/project.pbxproj +++ b/OathVideoPartnerSDK.xcodeproj/project.pbxproj @@ -361,6 +361,34 @@ remoteGlobalIDString = 50582F5A1E65C41900B18908; remoteInfo = PlayerControls; }; + 50AC123821C414E400B428D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DE611A791E9D40F200D253B2 /* PlayerControls.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 50582F5A1E65C41900B18908; + remoteInfo = PlayerControls; + }; + 50AC123A21C414E400B428D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DE2BBB281E8BEE2F00CA4296 /* VideoRenderer.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = DEA993831E83FE0600EB3B8A; + remoteInfo = VideoRenderer; + }; + 50AC123C21C414E400B428D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 06E6F4CC213DA6FF008BAA23 /* PlayerCore.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 06CD5298213D8D0700C5B783; + remoteInfo = PlayerCore; + }; + 50AC124421C414ED00B428D1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 06E6F4CC213DA6FF008BAA23 /* PlayerCore.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 06CD5298213D8D0700C5B783; + remoteInfo = PlayerCore; + }; DE4C51261C8071D500BFFB0B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = DEF3CBAE1C7F12D200CB5A74 /* Project object */; @@ -1329,6 +1357,7 @@ buildRules = ( ); dependencies = ( + 50AC124521C414ED00B428D1 /* PBXTargetDependency */, ); name = OathVideoPartnerSDK_tvOS; productName = OneSDK; @@ -1349,6 +1378,9 @@ buildRules = ( ); dependencies = ( + 50AC123921C414E400B428D1 /* PBXTargetDependency */, + 50AC123B21C414E400B428D1 /* PBXTargetDependency */, + 50AC123D21C414E400B428D1 /* PBXTargetDependency */, 5033927A1E96AFCA002562D9 /* PBXTargetDependency */, ); name = OathVideoPartnerSDK_iOS; @@ -1889,6 +1921,26 @@ name = PlayerControls; targetProxy = 503392791E96AFCA002562D9 /* PBXContainerItemProxy */; }; + 50AC123921C414E400B428D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PlayerControls; + targetProxy = 50AC123821C414E400B428D1 /* PBXContainerItemProxy */; + }; + 50AC123B21C414E400B428D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = VideoRenderer; + targetProxy = 50AC123A21C414E400B428D1 /* PBXContainerItemProxy */; + }; + 50AC123D21C414E400B428D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PlayerCore; + targetProxy = 50AC123C21C414E400B428D1 /* PBXContainerItemProxy */; + }; + 50AC124521C414ED00B428D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PlayerCore; + targetProxy = 50AC124421C414ED00B428D1 /* PBXContainerItemProxy */; + }; DE4C51271C8071D500BFFB0B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DE4C511A1C8071D500BFFB0B /* OathVideoPartnerSDK_iOS */; diff --git a/OathVideoPartnerSDK.xcodeproj/xcshareddata/xcschemes/OathVideoPartnerSDK_iOS.xcscheme b/OathVideoPartnerSDK.xcodeproj/xcshareddata/xcschemes/OathVideoPartnerSDK_iOS.xcscheme index 8c9dd60..a05db2d 100644 --- a/OathVideoPartnerSDK.xcodeproj/xcshareddata/xcschemes/OathVideoPartnerSDK_iOS.xcscheme +++ b/OathVideoPartnerSDK.xcodeproj/xcshareddata/xcschemes/OathVideoPartnerSDK_iOS.xcscheme @@ -34,6 +34,34 @@ ReferencedContainer = "container:PlayerCore/PlayerCore.xcodeproj"> + + + + + + + + - - - - - - - - Date: Mon, 17 Dec 2018 18:50:47 +0200 Subject: [PATCH 3/4] CPM implementation in pixels and logic --- .travis.yml | 6 +- PlayerCore | 2 +- sources/advertisements/AdURLProvider.swift | 10 +-- .../advertisements/AdURLProviderTests.swift | 2 +- sources/advertisements/AdVRMEngine.swift | 9 +-- sources/advertisements/VRMProvider.swift | 6 ++ .../TrackingPixelsConnector_Ad.swift | 39 ++++++++---- .../TrackingPixelsGenerator.swift.erb | 9 ++- .../TrackingPixelsGenerator.swift.rb | 63 +++++++++++++++++++ .../TrackingPixelsReporter.swift | 14 ++--- 10 files changed, 126 insertions(+), 34 deletions(-) create mode 100644 sources/metrics/tracking pixels/TrackingPixelsGenerator.swift.rb diff --git a/.travis.yml b/.travis.yml index 02369c4..36a29d5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,12 +2,15 @@ cache: bundler: true directories: - Carthage/Build + git: depth: 1 + install: - bundle install - brew install sourcery - carthage update --platform iOS + matrix: include: - os: osx @@ -17,9 +20,10 @@ matrix: script: - bundle exec fastlane test - bundle exec danger || true + notifications: email: false slack: - secure: KvNEEFAstBqYij4/AXkZGQUbYH++l+hQvDbrAxl4i1U/DWX+w5LcnPJ9gHedXIzgSedSsQjXQJDzyS/+uWAiauIYoiUcdHVEB/X+K3XCQj1bntS80s6epay2PrdPUnZ3V0p4G4KKabBSZK9VgmjrAKz33JX0uwCKc70ugq7B7iaPmTwkmiRbtaInIy8xUhJfypEw19PpMznkW/2R0RkJL3tNpBYolv96eMMYZ6lKJQbNZpmlkMuit8rgDJMHCDTX9W16lYx1Xb7lsRJzTSXGuPj3xSv14dExyUaXPTaeuSzrMz3jJJ+M679rIviiKKJybe+q37CMopzNwkSTZy349qcjyZzdakSpFG8MJ2IB/R8Uo+EcBLzi/RiAXd9+7UTmefijw6k6rLYNpNeYO2f00B+WppgnoyTKnTTSQbX4eekiIr4E7AQusz78r133UKmz4fUHVAj53GYCvSDxxRmPpSofB1BBTIFMZJPFN1a0AzRFP6dDYaOP0Ebsjv9ONViJtrZ8ZjQrQV8EsnogN5A8+Dg1yDzfXspke28892mSYq1lZmcGbrxkSjBpejP6FDJNZ4ytnHoQVPW4fJowqKXkyrFZ92gOAqvI+vS/x6adkidwd1zG8JroHDK2hw5aAuXN1/ktVBsDbyO5TYE0Mi76dMan5WZNjbWGGG2CBZvjXoo= + secure: HY+kZDjc2HSg+Ernsqvq8simGa7bZUW2DA4G6Rxiuy29jeVNifY3Yqqr61YFRU/Y0ppcqEK/+K37/l+j/GvmGZaW0ICPObe1uUXfx6KIcPBfjNiEfOKdYkUJc6aa4rI7PpbyCe1ja6mOxyvolD8aqOyi77K5j5x7/h/l4UprnKhzDYvTLcEpMoqEQv+s64zccs9X5hXMdHi08yqfiJ8xaUTydIU3UIuOI2vJi7MYhTOVuLfdvby0fr1Q76O8DPTm1T0utP50iovy1pKmF2LYmxV7U+l85SkMmxSLK4C5DAHWZhl17Bk7EQFWBfrTWkJ24KVQHzLCZcLJXcGw64SRrDr+xeIkW/wA3hivPw5NXn/4UOGbSdOmX+29sSey9R93Tp2DC8jlbGHs4r5Xkz8uhkxlaw+Q9pbOB9dk8yUv4Bsdfj0JAdq3DPOLDJaVY2sRU6Tx9oiCD5T3yME9yPEwQpO7gmIhdgFq/8tyzDKGNnJySZVE5KXnjrLndMUsVRRaxM+vTm+/3tAo5eMeA76ulNfxdX0LJ2kHlNe31w6eKI5TJNni8ZJ7DLhbsrW0JFi3fmGZyW+wxG0vA2nAUgRJ5UNn5YHNlg6Tns5YwUxUxy8NQyXKNEyONUh84u8X3c6ccqPWoQi66i22I+Icj6A4NPWS/8j/g1SU6Sy/apmP2/Q= on_success: never on_failure: always diff --git a/PlayerCore b/PlayerCore index 1a8e257..8051f23 160000 --- a/PlayerCore +++ b/PlayerCore @@ -1 +1 @@ -Subproject commit 1a8e257b4c9cfb47c7e40273f6d60704d42bf788 +Subproject commit 8051f2309c183c7f550a6d5ce609073bef5b45c0 diff --git a/sources/advertisements/AdURLProvider.swift b/sources/advertisements/AdURLProvider.swift index bff9781..ec1a304 100644 --- a/sources/advertisements/AdURLProvider.swift +++ b/sources/advertisements/AdURLProvider.swift @@ -4,14 +4,14 @@ import Foundation import PlayerCore struct AdURLProvider { - let groupsFetch: (URL) -> Future<[[VRMProvider.Item]]?> + let groupsFetch: (URL) -> Future let processItem: (VRMProvider.Item) -> Future let softTimeoutAction: (TimeInterval, @escaping Action) -> Void let hardTimeoutAction: (TimeInterval, @escaping Action) -> Void let softTimeoutValue: TimeInterval let hardTimeoutValue: TimeInterval - init(groupsFetch: @escaping (URL) -> Future<[[VRMProvider.Item]]?>, + init(groupsFetch: @escaping (URL) -> Future, processItem: @escaping (VRMProvider.Item) -> Future, softTimeoutAction: @escaping (TimeInterval, @escaping Action) -> Void, hardTimeoutAction: @escaping (TimeInterval, @escaping Action) -> Void, @@ -53,11 +53,11 @@ struct AdURLProvider { func requestGroups() { process.requestGroups() self.groupsFetch(url).onComplete { result in - if let groups = result { + if let response = result { self.queue.async { if !isStopped { - process.didReceiveGroups(groups) - request.inputs.didReceiveGroups(groups) + process.didReceiveGroups(response.items) + request.inputs.didReceiveGroups(response.items) self.softTimeoutAction(self.softTimeoutValue) { self.queue.async { diff --git a/sources/advertisements/AdURLProviderTests.swift b/sources/advertisements/AdURLProviderTests.swift index e55dbbd..a6b78c9 100644 --- a/sources/advertisements/AdURLProviderTests.swift +++ b/sources/advertisements/AdURLProviderTests.swift @@ -27,7 +27,7 @@ class AdURLProviderTests: XCTestCase { } } - let groupsContext = AsyncContext() + let groupsContext = AsyncContext() let itemContext = AsyncContext() let softTimeoutContext = AsyncContext() let hardTimeoutContext = AsyncContext() diff --git a/sources/advertisements/AdVRMEngine.swift b/sources/advertisements/AdVRMEngine.swift index 51e551f..e5774a4 100644 --- a/sources/advertisements/AdVRMEngine.swift +++ b/sources/advertisements/AdVRMEngine.swift @@ -11,14 +11,15 @@ class AdVRMEngine { self.dispatcher = dispatcher } - func requestAds(using request: @escaping (URL) -> Future) -> (URL) -> Future<[[VRMProvider.Item]]?> { + func requestAds(using request: @escaping (URL) -> Future) -> (URL) -> Future { return { url in - return request(url).map { [weak self] result in + return request(url).map { [weak self] result -> VRMProvider.Response? in guard let `self` = self else { return nil } guard let response = result else { return nil } self.dispatcher(PlayerCore.adProcessGroup(transactionId: response.transactionId, - slot: response.slot)) - return response.items + slot: response.slot, + cpm: response.cpm)) + return response } } } diff --git a/sources/advertisements/VRMProvider.swift b/sources/advertisements/VRMProvider.swift index 358437f..631ec3a 100644 --- a/sources/advertisements/VRMProvider.swift +++ b/sources/advertisements/VRMProvider.swift @@ -9,6 +9,7 @@ struct VRMProvider { struct Response { let transactionId: String? let slot: String + let cpm: CostPerMille? let items: [[Item]] } @@ -24,10 +25,15 @@ struct VRMProvider { return try json.parse("aeg") } + static func parseCpm(from json: JSON) throws -> CostPerMille? { + return json.parse("cpm") + } + static func parse(json: JSON) throws -> Response { return Response( transactionId: parseTransactionId(from: json), slot: try parseSlot(from: json), + cpm: try parseCpm(from: json), items: try parseGroups(from: json).map { try $0.map(parseItem) }) } diff --git a/sources/metrics/tracking pixels/TrackingPixelsConnector_Ad.swift b/sources/metrics/tracking pixels/TrackingPixelsConnector_Ad.swift index 3def101..29649d6 100644 --- a/sources/metrics/tracking pixels/TrackingPixelsConnector_Ad.swift +++ b/sources/metrics/tracking pixels/TrackingPixelsConnector_Ad.swift @@ -39,10 +39,12 @@ extension TrackingPixels.Connector { info: OathVideoPartnerSDK.info(from: start.info), type: adType, transactionId: start.transactionID, - videoViewUID: state.playbackSession.id.uuidString) + videoViewUID: state.playbackSession.id.uuidString, + cpm: state.adVRMManager.cpm) reporter.adServerRequest(info: OathVideoPartnerSDK.info(from: start.info), videoIndex: state.playlist.currentIndex, - videoViewUID: state.playbackSession.id.uuidString) + videoViewUID: state.playbackSession.id.uuidString, + cpm: state.adVRMManager.cpm) case .completeItem(let item): reporter.adEngineResponse(videoIndex: state.playlist.currentIndex, @@ -53,7 +55,8 @@ extension TrackingPixels.Connector { timeout: item.timeoutBarrier, fillType: item.fillType, transactionId: item.transactionID, - videoViewUID: state.playbackSession.id.uuidString) + videoViewUID: state.playbackSession.id.uuidString, + cpm: state.adVRMManager.cpm) case .timeoutItem(let timeout): reporter.adEngineResponse(videoIndex: state.playlist.currentIndex, info: OathVideoPartnerSDK.info(from: timeout.info), @@ -63,7 +66,8 @@ extension TrackingPixels.Connector { timeout: timeout.timeoutBarrier, fillType: timeout.fillType, transactionId: timeout.transactionID, - videoViewUID: state.playbackSession.id.uuidString) + videoViewUID: state.playbackSession.id.uuidString, + cpm: state.adVRMManager.cpm) case .otherErrorItem(let other): reporter.adEngineResponse(videoIndex: state.playlist.currentIndex, info: OathVideoPartnerSDK.info(from: other.info), @@ -73,7 +77,8 @@ extension TrackingPixels.Connector { timeout: nil, fillType: other.fillType, transactionId: other.transactionID, - videoViewUID: state.playbackSession.id.uuidString) + videoViewUID: state.playbackSession.id.uuidString, + cpm: state.adVRMManager.cpm) } } struct Payload { @@ -93,7 +98,8 @@ extension TrackingPixels.Connector { autoplay: model.isAutoplayEnabled, transactionId: payload.transactionID, adId: payload.adID, - videoViewUID: state.playbackSession.id.uuidString) + videoViewUID: state.playbackSession.id.uuidString, + cpm: state.adVRMManager.cpm) } func report(with function: (Payload) -> ()) { @@ -153,7 +159,8 @@ extension TrackingPixels.Connector { adId: holder.adID, transactionId: state.transactionIDHolder?.transactionID, adCurrentTime: result.time, - adDuration: result.duration) + adDuration: result.duration, + cpm: state.adVRMManager.cpm) } } /* Slot Opportunity Detector */ do { @@ -215,7 +222,8 @@ extension TrackingPixels.Connector { autoplay: model.isAutoplayEnabled, transactionId: state.transactionIDHolder?.transactionID, adId: holder.adID, - videoViewUID: state.playbackSession.id.uuidString) + videoViewUID: state.playbackSession.id.uuidString, + cpm: state.adVRMManager.cpm) } } @@ -280,7 +288,8 @@ extension TrackingPixels.Connector { reporter.sendBeacon(urls: payload.pixels.start) reporter.adStart(info: payload.info, videoIndex: state.playlist.currentIndex, - videoViewUID: state.playbackSession.id.uuidString) + videoViewUID: state.playbackSession.id.uuidString, + cpm: state.adVRMManager.cpm) } case .AdVideoFirstQuartile: report { payload in @@ -316,7 +325,8 @@ extension TrackingPixels.Connector { stage: .load, transactionId: state.transactionIDHolder?.transactionID, adId: holder.adID, - videoViewUID: state.playerSession.id.uuidString) + videoViewUID: state.playerSession.id.uuidString, + cpm: state.adVRMManager.cpm) default: break } } @@ -331,7 +341,8 @@ extension TrackingPixels.Connector { engineFlow(stage: .started, payload: payload) reporter.adStart(info: payload.info, videoIndex: state.playlist.currentIndex, - videoViewUID: state.playbackSession.id.uuidString) + videoViewUID: state.playbackSession.id.uuidString, + cpm: state.adVRMManager.cpm) } guard let duration = state.duration.ad?.seconds else { return } let volume: Float = state.mute.player ? 0 : 1 @@ -351,7 +362,8 @@ extension TrackingPixels.Connector { autoplay: model.isAutoplayEnabled, transactionId: state.transactionIDHolder?.transactionID, adId: holder.adID, - videoViewUID: state.playbackSession.id.uuidString) + videoViewUID: state.playbackSession.id.uuidString, + cpm: state.adVRMManager.cpm) case .nothing: break } @@ -505,7 +517,8 @@ extension TrackingPixels.Connector { stage: .load, transactionId: state.transactionIDHolder?.transactionID, adId: holder.adID, - videoViewUID: state.playerSession.id.uuidString) + videoViewUID: state.playerSession.id.uuidString, + cpm: state.adVRMManager.cpm) } } diff --git a/sources/metrics/tracking pixels/TrackingPixelsGenerator.swift.erb b/sources/metrics/tracking pixels/TrackingPixelsGenerator.swift.erb index 738e8f4..ade42c7 100644 --- a/sources/metrics/tracking pixels/TrackingPixelsGenerator.swift.erb +++ b/sources/metrics/tracking pixels/TrackingPixelsGenerator.swift.erb @@ -5,8 +5,13 @@ import Foundation <% require 'YAML' require 'FileUtils' -path = "mobile sdk evolution/definitions/tracking pixels/tracking-pixels.yaml" -api = YAML.load(File.read(path)).map { |request_name, fields| +file = nil +Dir.chdir('..') do + path = "mobile-sdk-evolution/definitions/tracking pixels/tracking-pixels.yaml" + file = File.read(path) +end + +api = YAML.load(file).map { |request_name, fields| fields[:request_name] = request_name fields["parameters"] = fields["parameters"].map { |key, value| { diff --git a/sources/metrics/tracking pixels/TrackingPixelsGenerator.swift.rb b/sources/metrics/tracking pixels/TrackingPixelsGenerator.swift.rb new file mode 100644 index 0000000..7fcfcaa --- /dev/null +++ b/sources/metrics/tracking pixels/TrackingPixelsGenerator.swift.rb @@ -0,0 +1,63 @@ +#coding:ASCII-8BIT +_erbout = ''; _erbout.concat "// Copyright 2018, Oath Inc.\n// Licensed under the terms of the MIT License. See LICENSE.md file in project root for terms.\nimport Foundation " + +; + +require 'YAML' +require 'FileUtils' + +file = nil +Dir.chdir('..') do + path = "mobile-sdk-evolution/definitions/tracking pixels/tracking-pixels.yaml" + file = File.read(path) +end + +api = YAML.load(file).map { |request_name, fields| + fields[:request_name] = request_name + fields["parameters"] = fields["parameters"].map { |key, value| + { + name: key, + nullable: value[0], + description: value[1] + } + } + fields +} + +def escapeDotsIn(parameterName) + parameterName.gsub('.','_') +end + +def parameterList(parameters) + parameters.map { |p| + "#{escapeDotsIn(p[:name])}: String#{p[:nullable] ? "? = nil" : "" }" + }.join(",\n\t\t") +end + +_erbout.concat "\n" +; _erbout.concat "\n" +; _erbout.concat "extension TrackingPixels {\n struct Generator {\n private init() {}\n }\n}\n\n" + + + + + +; _erbout.concat "extension TrackingPixels.Generator {\n " +; for call in api ; _erbout.concat "\n" +; _erbout.concat " static func "; _erbout.concat((call[:request_name]).to_s); _erbout.concat "(\n " +; _erbout.concat(( parameterList(call["parameters"]) ).to_s); _erbout.concat ") -> URLComponents\n {\n var queryItems = [URLQueryItem]()\n \n " + + + +; for p in call["parameters"]; name = escapeDotsIn(p[:name]); if !p[:nullable]; _erbout.concat "queryItems.append(URLQueryItem(name: \""; _erbout.concat((p[:name]).to_s); _erbout.concat "\", value: "; _erbout.concat((name).to_s); _erbout.concat "))\n " +; else; _erbout.concat "if let "; _erbout.concat((name).to_s); _erbout.concat " = "; _erbout.concat((name).to_s); _erbout.concat " { queryItems.append(URLQueryItem(name: \""; _erbout.concat((p[:name]).to_s); _erbout.concat "\", value: "; _erbout.concat((name).to_s); _erbout.concat ")) }\n " +; end; end; _erbout.concat "\n" +; _erbout.concat " var components = URLComponents()\n components.path = \"" +; _erbout.concat((call["anchor"]).to_s); _erbout.concat "\"\n components.queryItems = queryItems\n \n return components\n }\n " + + + + +; end; _erbout.concat "\n" +; _erbout.concat "}\n" +; _erbout.force_encoding(__ENCODING__) diff --git a/sources/metrics/tracking pixels/TrackingPixelsReporter.swift b/sources/metrics/tracking pixels/TrackingPixelsReporter.swift index c0aadba..800dafd 100644 --- a/sources/metrics/tracking pixels/TrackingPixelsReporter.swift +++ b/sources/metrics/tracking pixels/TrackingPixelsReporter.swift @@ -375,7 +375,7 @@ extension TrackingPixels.Reporter { transactionId: String?, adCurrentTime: Double, adDuration: Double, - cpm: CostPerMille) { + cpm: CostPerMille?) { sendMetric(.tracking( TrackingPixels.Generator.adViewTime( @@ -406,7 +406,7 @@ extension TrackingPixels.Reporter { type: Ad.Metrics.PlayType, transactionId: String?, videoViewUID: String, - cpm: CostPerMille) { + cpm: CostPerMille?) { sendMetric(.tracking( TrackingPixels.Generator.adEngineRequest( app_id: context.applicationID, @@ -441,7 +441,7 @@ extension TrackingPixels.Reporter { fillType: Ad.Metrics.FillType?, transactionId: String?, videoViewUID: String, - cpm: CostPerMille) { + cpm: CostPerMille?) { sendMetric(.tracking( TrackingPixels.Generator.adEngineResponse( app_id: context.applicationID, @@ -479,7 +479,7 @@ extension TrackingPixels.Reporter { transactionId: String?, adId: String?, videoViewUID: String, - cpm: CostPerMille) { + cpm: CostPerMille?) { sendMetric(.tracking( TrackingPixels.Generator.adIssue( app_id: context.applicationID, @@ -518,7 +518,7 @@ extension TrackingPixels.Reporter { transactionId: String?, adId: String?, videoViewUID: String, - cpm: CostPerMille) { + cpm: CostPerMille?) { sendMetric(.tracking( TrackingPixels.Generator.adEngineFlow( app_id: context.applicationID, @@ -602,7 +602,7 @@ extension TrackingPixels.Reporter { func adStart(info: Ad.Metrics.Info, videoIndex: Int, videoViewUID: String, - cpm: CostPerMille) { + cpm: CostPerMille?) { sendMetric(.advertisement( TrackingPixels.Generator.adStart( app_id: context.applicationID, @@ -622,7 +622,7 @@ extension TrackingPixels.Reporter { func adServerRequest(info: Ad.Metrics.Info, videoIndex: Int, videoViewUID: String, - cpm: CostPerMille) { + cpm: CostPerMille?) { sendMetric(.advertisement( TrackingPixels.Generator.adServerRequest( app_id: context.applicationID, From 88273252acd6a9917a51b98570263758043b627b Mon Sep 17 00:00:00 2001 From: Andrey Moskvin Date: Mon, 17 Dec 2018 19:31:33 +0200 Subject: [PATCH 4/4] Tests --- PlayerCore | 2 +- .../advertisements/AdURLProviderTests.swift | 6 +++++- .../VRMRequestControllerTest.swift | 1 + sources/advertisements/VRMProviderTests.swift | 21 ++++++++++++++++++- .../detectors/vrm/VRMDetectorTests.swift | 15 +++++++++++++ 5 files changed, 42 insertions(+), 3 deletions(-) diff --git a/PlayerCore b/PlayerCore index 8051f23..eddccd8 160000 --- a/PlayerCore +++ b/PlayerCore @@ -1 +1 @@ -Subproject commit 8051f2309c183c7f550a6d5ce609073bef5b45c0 +Subproject commit eddccd8e0123efacfa172c72ad70c168931419d4 diff --git a/sources/advertisements/AdURLProviderTests.swift b/sources/advertisements/AdURLProviderTests.swift index a6b78c9..82e2c0c 100644 --- a/sources/advertisements/AdURLProviderTests.swift +++ b/sources/advertisements/AdURLProviderTests.swift @@ -75,8 +75,12 @@ class AdURLProviderTests: XCTestCase { [ item ], [ item ] ] + let response = VRMProvider.Response(transactionId: nil, + slot: "slot", + cpm: "cpm", + items:groups) - groupsContext.callbacks[0](groups) + groupsContext.callbacks[0](response) provider.queue.sync {} XCTAssertEqual(softTimeoutContext.callbacks.count, 1) diff --git a/sources/advertisements/VRM New Core/Controllers/VRMRequestControllerTest.swift b/sources/advertisements/VRM New Core/Controllers/VRMRequestControllerTest.swift index bfda907..462e8e4 100644 --- a/sources/advertisements/VRM New Core/Controllers/VRMRequestControllerTest.swift +++ b/sources/advertisements/VRM New Core/Controllers/VRMRequestControllerTest.swift @@ -71,6 +71,7 @@ class VRMRequestControllerTest: XCTestCase { return Future(value: VRMProvider.Response(transactionId: "transactionId", slot: "slot", + cpm: "cpm", items: self.itemsResponse)) }) diff --git a/sources/advertisements/VRMProviderTests.swift b/sources/advertisements/VRMProviderTests.swift index b3de0e7..dd89bf9 100644 --- a/sources/advertisements/VRMProviderTests.swift +++ b/sources/advertisements/VRMProviderTests.swift @@ -5,7 +5,7 @@ import Quick import Nimble @testable import OathVideoPartnerSDK -class VRMCallTests: QuickSpec { +class VRMProviderTests: QuickSpec { override func spec() { //swiftlint:disable:this function_body_length describe("groups parsing") { let parse = VRMProvider.parseGroups @@ -60,6 +60,25 @@ class VRMCallTests: QuickSpec { } } + describe("cpm parsing") { + it("should be successful even if value is missing") { + expect { + let result = try VRMProvider.parseCpm(from: [:]) + expect(result).to(beNil()) + return result + }.toNot(throwError()) + } + + it("should parse succesful if there is cpm value") { + expect { + let result = try VRMProvider.parseCpm(from: ["cpm" : "cpm"]) + expect(result).toNot(beNil()) + expect(result) == "cpm" + return result + }.toNot(throwError()) + } + } + describe("url parsing") { let parse = VRMProvider.parseURL let url = URL(string: "http://test.com")! diff --git a/sources/metrics/detectors/vrm/VRMDetectorTests.swift b/sources/metrics/detectors/vrm/VRMDetectorTests.swift index 5536942..a925296 100644 --- a/sources/metrics/detectors/vrm/VRMDetectorTests.swift +++ b/sources/metrics/detectors/vrm/VRMDetectorTests.swift @@ -35,6 +35,7 @@ class VRMDetectorTests: XCTestCase { func testEmptyDetection() { let result = detector.process( state: .init(timeoutBarrier: 3500, + cpm: nil, requestsFired: 0, request: .init(id: UUID(), timeout: .beforeSoft, @@ -45,6 +46,7 @@ class VRMDetectorTests: XCTestCase { func testVRMRequests() { let id1 = UUID() var result = detector.process(state: .init(timeoutBarrier: 3500, + cpm: nil, requestsFired: 0, request: .init(id: id1, timeout: .beforeSoft, @@ -52,6 +54,7 @@ class VRMDetectorTests: XCTestCase { XCTAssertEqual(result.count, 0) result = detector.process(state: .init(timeoutBarrier: 3500, + cpm: nil, requestsFired: 0, request: .init(id: id1, timeout: .beforeSoft, @@ -59,6 +62,7 @@ class VRMDetectorTests: XCTestCase { XCTAssertEqual(result.count, 0) result = detector.process(state: .init(timeoutBarrier: 3500, + cpm: nil, requestsFired: 0, request: .init(id: id1, timeout: .beforeSoft, @@ -74,6 +78,7 @@ class VRMDetectorTests: XCTestCase { } result = detector.process(state: .init(timeoutBarrier: 3500, + cpm: nil, requestsFired: 0, request: .init(id: UUID(), timeout: .beforeSoft, @@ -113,6 +118,7 @@ class VRMDetectorTests: XCTestCase { sut.startItems.insert(startItem1) var result = detector.process(state: .init(timeoutBarrier: 3500, + cpm: nil, requestsFired: 0, request: .init(id: id, timeout: .afterSoft, @@ -128,6 +134,7 @@ class VRMDetectorTests: XCTestCase { sut.startItems.insert(startItem1) result = detector.process(state: .init(timeoutBarrier: 3500, + cpm: nil, requestsFired: 0, request: .init(id: id, timeout: .afterSoft, @@ -138,6 +145,7 @@ class VRMDetectorTests: XCTestCase { sut.startItems.insert(startItem2) result = detector.process(state: .init(timeoutBarrier: 3500, + cpm: nil, requestsFired: 0, request: .init(id: id, timeout: .afterSoft, @@ -170,6 +178,7 @@ class VRMDetectorTests: XCTestCase { completeItem: nil) sut.completeItem = completeItem1 var result = detector.process(state: .init(timeoutBarrier: 3500, + cpm: nil, requestsFired: 0, request: .init(id: id, timeout: .afterSoft, @@ -206,6 +215,7 @@ class VRMDetectorTests: XCTestCase { completeItem: nil) sut.timeoutItems.insert(timeoutItem1) var result = detector.process(state: .init(timeoutBarrier: 3500, + cpm: nil, requestsFired: 0, request: .init(id: id, timeout: .afterSoft, @@ -219,6 +229,7 @@ class VRMDetectorTests: XCTestCase { } result = detector.process(state: .init(timeoutBarrier: 3500, + cpm: nil, requestsFired: 0, request: .init(id: id, timeout: .afterSoft, @@ -229,6 +240,7 @@ class VRMDetectorTests: XCTestCase { sut.timeoutItems.insert(timeoutItem1) sut.timeoutItems.insert(timeoutItem2) result = detector.process(state: .init(timeoutBarrier: 3500, + cpm: nil, requestsFired: 0, request: .init(id: id, timeout: .afterSoft, @@ -267,6 +279,7 @@ class VRMDetectorTests: XCTestCase { sut.otherErrorItems.insert(otherErrorItem1) var result = detector.process(state: .init(timeoutBarrier: 3500, + cpm: nil, requestsFired: 0, request: .init(id: id, timeout: .afterSoft, @@ -281,6 +294,7 @@ class VRMDetectorTests: XCTestCase { sut.otherErrorItems.insert(otherErrorItem1) result = detector.process(state: .init(timeoutBarrier: 3500, + cpm: nil, requestsFired: 0, request: .init(id: id, timeout: .afterSoft, @@ -291,6 +305,7 @@ class VRMDetectorTests: XCTestCase { sut.otherErrorItems.insert(otherErrorItem1) sut.otherErrorItems.insert(otherErrorItem2) result = detector.process(state: .init(timeoutBarrier: 3500, + cpm: nil, requestsFired: 0, request: .init(id: id, timeout: .afterSoft,