Skip to content

Commit 3db2e1b

Browse files
authored
fix: change the types of event revenue and value fields (#467)
1 parent 726ee35 commit 3db2e1b

File tree

4 files changed

+63
-31
lines changed

4 files changed

+63
-31
lines changed

Sources/Data Model/DispatchEvents/BatchEvent.swift

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright 2019-2021, Optimizely, Inc. and contributors
2+
// Copyright 2019-2022, Optimizely, Inc. and contributors
33
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
@@ -120,8 +120,8 @@ struct DispatchEvent: Codable, Equatable {
120120
let timestamp: Int64
121121
let uuid: String
122122
var tags: [String: AttributeValue]?
123-
var revenue: AttributeValue?
124-
var value: AttributeValue?
123+
var revenue: Int64?
124+
var value: Double?
125125

126126
enum CodingKeys: String, CodingKey {
127127
case entityID = "entity_id"
@@ -138,11 +138,9 @@ struct DispatchEvent: Codable, Equatable {
138138
entityID: String,
139139
uuid: String,
140140
tags: [String: AttributeValue]? = [:],
141-
value: AttributeValue? = nil,
142-
revenue: AttributeValue? = nil) {
143-
144-
// TODO: add validation and throw here for invalid value (int, double) and revenue (int) types
145-
141+
value: Double? = nil,
142+
revenue: Int64? = nil) {
143+
146144
self.timestamp = timestamp
147145
self.key = key
148146
self.entityID = entityID

Sources/Implementation/Events/BatchEventBuilder.swift

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright 2019, 2021, Optimizely, Inc. and contributors
2+
// Copyright 2019, 2021-2022, Optimizely, Inc. and contributors
33
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
@@ -108,7 +108,7 @@ class BatchEventBuilder {
108108

109109
// MARK: - Event Tags
110110

111-
static func filterEventTags(_ eventTags: [String: Any]?) -> ([String: AttributeValue], AttributeValue?, AttributeValue?) {
111+
static func filterEventTags(_ eventTags: [String: Any]?) -> ([String: AttributeValue], Double?, Int64?) {
112112
guard let eventTags = eventTags else {
113113
return ([:], nil, nil)
114114
}
@@ -124,54 +124,53 @@ class BatchEventBuilder {
124124
}
125125

126126
static func filterTagsWithInvalidTypes(_ eventTags: [String: Any]) -> [String: AttributeValue] {
127-
let filteredTags = eventTags.mapValues { AttributeValue(value: $0) }.filter { $0.value != nil } as? [String: AttributeValue]
128-
return filteredTags ?? [:]
127+
return eventTags.compactMapValues { AttributeValue(value: $0) }
129128
}
130129

131-
static func extractValueEventTag(_ eventTags: [String: AttributeValue]) -> AttributeValue? {
130+
static func extractValueEventTag(_ eventTags: [String: AttributeValue]) -> Double? {
132131
guard let valueFromTags = eventTags[DispatchEvent.valueKey] else { return nil }
133132

134133
// export {value, revenue} only for {double, int64} types
135-
var value: AttributeValue?
134+
var value: Double?
136135

137136
switch valueFromTags {
138-
case .double:
137+
case .double(let attrValue):
139138
// valid value type
140-
value = valueFromTags
141-
case .int(let int64Value):
142-
value = AttributeValue(value: Double(int64Value))
139+
value = attrValue
140+
case .int(let attrValue):
141+
value = Double(attrValue)
143142
default:
144143
value = nil
145144
}
146145

147146
if let value = value {
148-
logger.i(.extractValueFromEventTags(value.stringValue))
147+
logger.i(.extractValueFromEventTags("\(value)"))
149148
} else {
150149
logger.i(.failedToExtractValueFromEventTags(valueFromTags.stringValue))
151150
}
152151

153152
return value
154153
}
155154

156-
static func extractRevenueEventTag(_ eventTags: [String: AttributeValue]) -> AttributeValue? {
155+
static func extractRevenueEventTag(_ eventTags: [String: AttributeValue]) -> Int64? {
157156
guard let revenueFromTags = eventTags[DispatchEvent.revenueKey] else { return nil }
158157

159158
// export {value, revenue} only for {double, int64} types
160-
var revenue: AttributeValue?
159+
var revenue: Int64?
161160

162161
switch revenueFromTags {
163-
case .int:
162+
case .int(let value):
164163
// valid revenue type
165-
revenue = revenueFromTags
166-
case .double(let doubleValue):
164+
revenue = Int64(value)
165+
case .double(let value):
167166
// not accurate but acceptable ("3.14" -> "3")
168-
revenue = AttributeValue(value: Int64(doubleValue))
167+
revenue = Int64(value)
169168
default:
170169
revenue = nil
171170
}
172171

173172
if let revenue = revenue {
174-
logger.i(.extractRevenueFromEventTags(revenue.stringValue))
173+
logger.i(.extractRevenueFromEventTags("\(revenue)"))
175174
} else {
176175
logger.i(.failedToExtractRevenueFromEventTags(revenueFromTags.stringValue))
177176
}

Tests/OptimizelyTests-Common/BatchEventBuilderTest.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright 2019-2021, Optimizely, Inc. and contributors
2+
// Copyright 2019-2022, Optimizely, Inc. and contributors
33
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
@@ -38,16 +38,22 @@ class BatchEventBuilderTests: XCTestCase {
3838
}
3939

4040
func testConversionEventWithNoExperiment() {
41-
let conversion = BatchEventBuilder.createConversionEvent(config: (optimizely?.config)!, eventKey: eventWithNoExperimentKey, userId: userId, attributes: ["anyattribute": "value", "broswer_type": "firefox"], eventTags: nil)
41+
// serialized to JSON
42+
let conversion = BatchEventBuilder.createConversionEvent(config: (optimizely?.config)!,
43+
eventKey: eventWithNoExperimentKey,
44+
userId: userId,
45+
attributes: ["anyattribute": "value", "broswer_type": "firefox"],
46+
eventTags: ["browser": "chrome"])
4247

4348
XCTAssertNotNil(conversion)
4449

50+
// deserialized from JSON
4551
let batchEvent = try? JSONDecoder().decode(BatchEvent.self, from: conversion!)
4652

4753
XCTAssertNotNil(batchEvent)
4854

4955
XCTAssert((batchEvent?.enrichDecisions)! == true)
50-
56+
XCTAssertEqual(batchEvent?.visitors[0].visitorID, userId)
5157
}
5258

5359
}

Tests/OptimizelyTests-Common/BatchEventBuilderTests_EventTags.swift

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright 2019, 2021, Optimizely, Inc. and contributors
2+
// Copyright 2019, 2021-2022, Optimizely, Inc. and contributors
33
//
44
// Licensed under the Apache License, Version 2.0 (the "License");
55
// you may not use this file except in compliance with the License.
@@ -315,7 +315,36 @@ extension BatchEventBuilderTests_EventTags {
315315
XCTAssertEqual(de["revenue"] as! Int, 40, "value must be valid for revenue")
316316
XCTAssertEqual(de["value"] as! Double, 32, "value must be valid for value")
317317
}
318-
318+
319+
func testEventTagsWithRevenueAndValue_toJSON() {
320+
321+
// valid revenue/value types
322+
323+
let conversion1 = BatchEventBuilder.createConversionEvent(config: (optimizely?.config)!, eventKey: eventKey, userId: userId, attributes: [:],
324+
eventTags: ["browser": "chrome",
325+
"revenue": 123,
326+
"value": 32.5])
327+
328+
// invalid revenue/value types
329+
330+
let conversion2 = BatchEventBuilder.createConversionEvent(config: (optimizely?.config)!, eventKey: eventKey, userId: userId, attributes: [:],
331+
eventTags: ["browser": "chrome",
332+
"revenue": true,
333+
"value": "invalid"])
334+
335+
// deserialized from JSON
336+
let batchEvent1 = try? JSONDecoder().decode(BatchEvent.self, from: conversion1!)
337+
let batchEvent2 = try? JSONDecoder().decode(BatchEvent.self, from: conversion2!)
338+
339+
XCTAssertEqual(batchEvent1?.visitors[0].visitorID, userId)
340+
XCTAssertEqual(batchEvent1?.visitors[0].snapshots[0].events[0].revenue, 123)
341+
XCTAssertEqual(batchEvent1?.visitors[0].snapshots[0].events[0].value, 32.5)
342+
343+
XCTAssertEqual(batchEvent2?.visitors[0].visitorID, userId)
344+
XCTAssertNil(batchEvent2?.visitors[0].snapshots[0].events[0].revenue, "invalid type not extracted")
345+
XCTAssertNil(batchEvent2?.visitors[0].snapshots[0].events[0].value, "invalid type not extracted")
346+
}
347+
319348
}
320349

321350
// MARK: - Utils

0 commit comments

Comments
 (0)