Skip to content
This repository has been archived by the owner on Apr 26, 2023. It is now read-only.

Commit

Permalink
Implemented logic for invalid time and added test for it
Browse files Browse the repository at this point in the history
  • Loading branch information
RomanTysiachnik committed Feb 12, 2019
1 parent 4cc5ac0 commit 7079d04
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 19 deletions.
73 changes: 58 additions & 15 deletions sources/advertisements/VASTParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,13 @@ enum VASTParser {
delegate.didStartElement = .some { (name, attr) -> Void in
if let skipOffset = attr["skipoffset"] {
if skipOffset.contains("%") {
guard let value = Int(skipOffset.replacingOccurrences(of: "%", with: "")) else { return }
inlineContext.skipOffset = .percentage(value)
if let value = Int(skipOffset.replacingOccurrences(of: "%", with: "")) {
inlineContext.skipOffset = .percentage(value)
}
} else if skipOffset.contains(":") {
guard let value = parseTime(from: skipOffset) else { return }
inlineContext.skipOffset = .time(value)
if let value = VASTTime(with: skipOffset)?.seconds {
inlineContext.skipOffset = .time(Double(value))
}
}
}

Expand Down Expand Up @@ -505,19 +507,60 @@ enum VASTParser {
return delegateStack
}

static func parseTime(from string: String) -> Double? {
let components = string.components(separatedBy: ":")
guard components.count == 3 else { return nil }
return components
.compactMap(Double.init)
.enumerated()
.map {
let multipliers: [Double] = [3600, 60, 1]
return $0.element * multipliers[$0.offset]
struct VASTTime {
enum Time {
case hours([String])
case minutes([String])
case seconds([String])

private var maxValue: Int {
switch self {
case .hours: return 99
case .minutes, .seconds: return 59
}
}
private var multiplier: Int {
switch self {
case .hours: return 3600
case .minutes: return 60
case .seconds: return 1
}
}
private var index: Int {
switch self {
case .hours: return 0
case .minutes: return 1
case .seconds: return 2
}
}
private var stringTime: String {
switch self {
case .hours(let value): return value[self.index]
case .minutes(let value): return value[self.index]
case .seconds(let value): return value[self.index]
}
}

var resultInSeconds: Int? {
guard let roundedSeconds = Double(self.stringTime)?.rounded() else { return nil }
let result = Int(roundedSeconds)
guard result <= maxValue else { return nil }
return result * multiplier
}
.reduce(0.0, +)

}

let seconds: Int

init?(with time: String) {
let components = time.components(separatedBy: ":")
guard components.count == 3,
let hours = Time.hours(components).resultInSeconds,
let minutes = Time.minutes(components).resultInSeconds,
let seconds = Time.seconds(components).resultInSeconds else { return nil }
self.seconds = hours + minutes + seconds
}
}


//swiftlint:disable line_length
//swiftlint:enable function_body_length
Expand Down
13 changes: 10 additions & 3 deletions sources/advertisements/VASTParserTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,17 +125,24 @@ class VASTParserTests: XCTestCase {
XCTAssertEqual(vpaidModel.pixels.collapse.first?.absoluteString, url + "collapse.gif")
}

func testParseAdSkipInTime() {
func testParseSkipOffsetInTime() {
let vast = getVAST(atPath: "VAST1")
guard let model = VASTParser.parseFrom(string: vast) else { return XCTFail("Failed to parse VAST VPAID xml") }
guard case let .inline(vpaidModel) = model else { return XCTFail() }
XCTAssertEqual(vpaidModel.skipOffset, .time(3663.123))
XCTAssertEqual(vpaidModel.skipOffset, .time(3663))
}

func testParseAdSkipInPersentage() {
func testParseSkipOffsetInPersentage() {
let vast = getVAST(atPath: "VASTExampleCDATA")
guard let model = VASTParser.parseFrom(string: vast) else { return XCTFail("Failed to parse VAST VPAID xml") }
guard case let .inline(vpaidModel) = model else { return XCTFail() }
XCTAssertEqual(vpaidModel.skipOffset, .percentage(32))
}

func testParseNotValidSkipOffsetInTime() {
let vast = getVAST(atPath: "VASTVerificationInExtension")
guard let model = VASTParser.parseFrom(string: vast) else { return XCTFail("Failed to parse VAST VPAID xml") }
guard case let .inline(vpaidModel) = model else { return XCTFail() }
XCTAssertEqual(vpaidModel.skipOffset, .none)
}
}
2 changes: 1 addition & 1 deletion sources/advertisements/VASTVerificationInExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<Impression><![CDATA[http://localhost:3000/6/beacons/vast/impression.gif?int=123&str=abc&macro=[HELLO]&url=https%3A%2F%2Fexample.com%2Fpath]]></Impression>
<Creatives>
<Creative>
<Linear>
<Linear skipoffset="01.5:60:64.123">
<Duration>
<![CDATA[00:00:30]]>
</Duration>
Expand Down

0 comments on commit 7079d04

Please sign in to comment.