mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
Posthog: use correct API for user properties (#2793)
This commit is contained in:
parent
6ca92c272a
commit
0eb1fb257c
@ -6733,15 +6733,15 @@ class PHGPostHogMock: PHGPostHogProtocol {
|
|||||||
}
|
}
|
||||||
//MARK: - capture
|
//MARK: - capture
|
||||||
|
|
||||||
var capturePropertiesUnderlyingCallsCount = 0
|
var capturePropertiesUserPropertiesUnderlyingCallsCount = 0
|
||||||
var capturePropertiesCallsCount: Int {
|
var capturePropertiesUserPropertiesCallsCount: Int {
|
||||||
get {
|
get {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
return capturePropertiesUnderlyingCallsCount
|
return capturePropertiesUserPropertiesUnderlyingCallsCount
|
||||||
} else {
|
} else {
|
||||||
var returnValue: Int? = nil
|
var returnValue: Int? = nil
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
returnValue = capturePropertiesUnderlyingCallsCount
|
returnValue = capturePropertiesUserPropertiesUnderlyingCallsCount
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnValue!
|
return returnValue!
|
||||||
@ -6749,26 +6749,26 @@ class PHGPostHogMock: PHGPostHogProtocol {
|
|||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
capturePropertiesUnderlyingCallsCount = newValue
|
capturePropertiesUserPropertiesUnderlyingCallsCount = newValue
|
||||||
} else {
|
} else {
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
capturePropertiesUnderlyingCallsCount = newValue
|
capturePropertiesUserPropertiesUnderlyingCallsCount = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var capturePropertiesCalled: Bool {
|
var capturePropertiesUserPropertiesCalled: Bool {
|
||||||
return capturePropertiesCallsCount > 0
|
return capturePropertiesUserPropertiesCallsCount > 0
|
||||||
}
|
}
|
||||||
var capturePropertiesReceivedArguments: (event: String, properties: [String: Any]?)?
|
var capturePropertiesUserPropertiesReceivedArguments: (event: String, properties: [String: Any]?, userProperties: [String: Any]?)?
|
||||||
var capturePropertiesReceivedInvocations: [(event: String, properties: [String: Any]?)] = []
|
var capturePropertiesUserPropertiesReceivedInvocations: [(event: String, properties: [String: Any]?, userProperties: [String: Any]?)] = []
|
||||||
var capturePropertiesClosure: ((String, [String: Any]?) -> Void)?
|
var capturePropertiesUserPropertiesClosure: ((String, [String: Any]?, [String: Any]?) -> Void)?
|
||||||
|
|
||||||
func capture(_ event: String, properties: [String: Any]?) {
|
func capture(_ event: String, properties: [String: Any]?, userProperties: [String: Any]?) {
|
||||||
capturePropertiesCallsCount += 1
|
capturePropertiesUserPropertiesCallsCount += 1
|
||||||
capturePropertiesReceivedArguments = (event: event, properties: properties)
|
capturePropertiesUserPropertiesReceivedArguments = (event: event, properties: properties, userProperties: userProperties)
|
||||||
capturePropertiesReceivedInvocations.append((event: event, properties: properties))
|
capturePropertiesUserPropertiesReceivedInvocations.append((event: event, properties: properties, userProperties: userProperties))
|
||||||
capturePropertiesClosure?(event, properties)
|
capturePropertiesUserPropertiesClosure?(event, properties, userProperties)
|
||||||
}
|
}
|
||||||
//MARK: - screen
|
//MARK: - screen
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ protocol PHGPostHogProtocol {
|
|||||||
|
|
||||||
func reset()
|
func reset()
|
||||||
|
|
||||||
func capture(_ event: String, properties: [String: Any]?)
|
func capture(_ event: String, properties: [String: Any]?, userProperties: [String: Any]?)
|
||||||
|
|
||||||
func screen(_ screenTitle: String, properties: [String: Any]?)
|
func screen(_ screenTitle: String, properties: [String: Any]?)
|
||||||
}
|
}
|
||||||
|
@ -69,12 +69,13 @@ class PostHogAnalyticsClient: AnalyticsClientProtocol {
|
|||||||
|
|
||||||
func capture(_ event: AnalyticsEventProtocol) {
|
func capture(_ event: AnalyticsEventProtocol) {
|
||||||
guard isRunning else { return }
|
guard isRunning else { return }
|
||||||
postHog?.capture(event.eventName, properties: attachUserProperties(to: attachSuperProperties(to: event.properties)))
|
postHog?.capture(event.eventName, properties: attachSuperProperties(to: event.properties), userProperties: pendingUserProperties?.properties.compactMapValues { $0 })
|
||||||
|
pendingUserProperties = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func screen(_ event: AnalyticsScreenProtocol) {
|
func screen(_ event: AnalyticsScreenProtocol) {
|
||||||
guard isRunning else { return }
|
guard isRunning else { return }
|
||||||
postHog?.screen(event.screenName.rawValue, properties: attachUserProperties(to: attachSuperProperties(to: event.properties)))
|
postHog?.screen(event.screenName.rawValue, properties: attachSuperProperties(to: event.properties))
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateUserProperties(_ userProperties: AnalyticsEvent.UserProperties) {
|
func updateUserProperties(_ userProperties: AnalyticsEvent.UserProperties) {
|
||||||
@ -106,21 +107,6 @@ class PostHogAnalyticsClient: AnalyticsClientProtocol {
|
|||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
/// Given a dictionary containing properties from an event, this method will return those properties
|
|
||||||
/// with any pending user properties included under the `$set` key.
|
|
||||||
/// - Parameter properties: A dictionary of properties from an event.
|
|
||||||
/// - Returns: The `properties` dictionary with any user properties included.
|
|
||||||
private func attachUserProperties(to properties: [String: Any]) -> [String: Any] {
|
|
||||||
guard isRunning, let userProperties = pendingUserProperties else { return properties }
|
|
||||||
|
|
||||||
var properties = properties
|
|
||||||
|
|
||||||
// As user properties overwrite old ones via $set, compactMap the dictionary to avoid resetting any missing properties
|
|
||||||
properties["$set"] = userProperties.properties.compactMapValues { $0 }
|
|
||||||
pendingUserProperties = nil
|
|
||||||
return properties
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Attach super properties to events.
|
/// Attach super properties to events.
|
||||||
/// If the property is already set on the event, the already set value will be kept.
|
/// If the property is already set on the event, the already set value will be kept.
|
||||||
private func attachSuperProperties(to properties: [String: Any]) -> [String: Any] {
|
private func attachSuperProperties(to properties: [String: Any]) -> [String: Any] {
|
||||||
|
@ -177,17 +177,35 @@ class AnalyticsTests: XCTestCase {
|
|||||||
|
|
||||||
func testSendingUserProperties() {
|
func testSendingUserProperties() {
|
||||||
// Given a client with user properties set
|
// Given a client with user properties set
|
||||||
let client = PostHogAnalyticsClient()
|
|
||||||
|
let client = PostHogAnalyticsClient(posthogFactory: MockPostHogFactory(mock: posthogMock))
|
||||||
|
client.start(analyticsConfiguration: appSettings.analyticsConfiguration)
|
||||||
|
|
||||||
client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: nil, ftueUseCaseSelection: .PersonalMessaging,
|
client.updateUserProperties(AnalyticsEvent.UserProperties(allChatsActiveFilter: nil, ftueUseCaseSelection: .PersonalMessaging,
|
||||||
numFavouriteRooms: nil,
|
numFavouriteRooms: nil,
|
||||||
numSpaces: nil))
|
numSpaces: nil))
|
||||||
client.start(analyticsConfiguration: appSettings.analyticsConfiguration)
|
|
||||||
|
|
||||||
XCTAssertNotNil(client.pendingUserProperties, "The user properties should be cached.")
|
XCTAssertNotNil(client.pendingUserProperties, "The user properties should be cached.")
|
||||||
XCTAssertEqual(client.pendingUserProperties?.ftueUseCaseSelection, .PersonalMessaging, "The use case selection should match.")
|
XCTAssertEqual(client.pendingUserProperties?.ftueUseCaseSelection, .PersonalMessaging, "The use case selection should match.")
|
||||||
|
|
||||||
// When sending an event (tests run under Debug configuration so this is sent to the development instance)
|
// When sending an event (tests run under Debug configuration so this is sent to the development instance)
|
||||||
client.screen(AnalyticsEvent.MobileScreen(durationMs: nil, screenName: .Home))
|
let someEvent = AnalyticsEvent.Error(context: nil,
|
||||||
|
cryptoModule: .Rust,
|
||||||
|
cryptoSDK: .Rust,
|
||||||
|
domain: .E2EE,
|
||||||
|
eventLocalAgeMillis: nil,
|
||||||
|
isFederated: nil,
|
||||||
|
isMatrixDotOrg: nil,
|
||||||
|
name: .OlmKeysNotSentError,
|
||||||
|
timeToDecryptMillis: nil,
|
||||||
|
userTrustsOwnIdentity: nil,
|
||||||
|
wasVisibleToUser: nil)
|
||||||
|
client.capture(someEvent)
|
||||||
|
|
||||||
|
let capturedEvent = posthogMock.capturePropertiesUserPropertiesReceivedArguments
|
||||||
|
|
||||||
|
// The user properties should have been added
|
||||||
|
XCTAssertEqual(capturedEvent?.userProperties?["ftueUseCaseSelection"] as? String, AnalyticsEvent.UserProperties.FtueUseCaseSelection.PersonalMessaging.rawValue)
|
||||||
|
|
||||||
// Then the properties should be cleared
|
// Then the properties should be cleared
|
||||||
XCTAssertNil(client.pendingUserProperties, "The user properties should be cleared.")
|
XCTAssertNil(client.pendingUserProperties, "The user properties should be cleared.")
|
||||||
@ -243,7 +261,7 @@ class AnalyticsTests: XCTestCase {
|
|||||||
wasVisibleToUser: nil)
|
wasVisibleToUser: nil)
|
||||||
client.capture(someEvent)
|
client.capture(someEvent)
|
||||||
|
|
||||||
let capturedEvent = posthogMock.capturePropertiesReceivedArguments
|
let capturedEvent = posthogMock.capturePropertiesUserPropertiesReceivedArguments
|
||||||
|
|
||||||
// All the super properties should have been added
|
// All the super properties should have been added
|
||||||
XCTAssertEqual(capturedEvent?.properties?["cryptoSDK"] as? String, AnalyticsEvent.SuperProperties.CryptoSDK.Rust.rawValue)
|
XCTAssertEqual(capturedEvent?.properties?["cryptoSDK"] as? String, AnalyticsEvent.SuperProperties.CryptoSDK.Rust.rawValue)
|
||||||
@ -258,7 +276,7 @@ class AnalyticsTests: XCTestCase {
|
|||||||
)
|
)
|
||||||
|
|
||||||
client.capture(someEvent)
|
client.capture(someEvent)
|
||||||
let capturedEvent2 = posthogMock.capturePropertiesReceivedArguments
|
let capturedEvent2 = posthogMock.capturePropertiesUserPropertiesReceivedArguments
|
||||||
|
|
||||||
// All the super properties should have been added, with the one udpated
|
// All the super properties should have been added, with the one udpated
|
||||||
XCTAssertEqual(capturedEvent2?.properties?["cryptoSDK"] as? String, AnalyticsEvent.SuperProperties.CryptoSDK.Rust.rawValue)
|
XCTAssertEqual(capturedEvent2?.properties?["cryptoSDK"] as? String, AnalyticsEvent.SuperProperties.CryptoSDK.Rust.rawValue)
|
||||||
@ -290,13 +308,13 @@ class AnalyticsTests: XCTestCase {
|
|||||||
wasVisibleToUser: nil)
|
wasVisibleToUser: nil)
|
||||||
client.capture(someEvent)
|
client.capture(someEvent)
|
||||||
|
|
||||||
XCTAssertEqual(posthogMock.capturePropertiesCalled, false)
|
XCTAssertEqual(posthogMock.capturePropertiesUserPropertiesCalled, false)
|
||||||
|
|
||||||
// start now
|
// start now
|
||||||
client.start(analyticsConfiguration: appSettings.analyticsConfiguration)
|
client.start(analyticsConfiguration: appSettings.analyticsConfiguration)
|
||||||
XCTAssertEqual(posthogMock.optInCalled, true)
|
XCTAssertEqual(posthogMock.optInCalled, true)
|
||||||
|
|
||||||
client.capture(someEvent)
|
client.capture(someEvent)
|
||||||
XCTAssertEqual(posthogMock.capturePropertiesCalled, true)
|
XCTAssertEqual(posthogMock.capturePropertiesUserPropertiesCalled, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user