Skip to content

Commit

Permalink
Merge branch 'release/7.138.0' into release/7.138.0-build-1
Browse files Browse the repository at this point in the history
  • Loading branch information
afterxleep committed Sep 17, 2024
2 parents c022370 + 741daa5 commit fdeb510
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 61 deletions.
10 changes: 5 additions & 5 deletions Core/PixelEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1619,11 +1619,11 @@ extension Pixel.Event {
case .pproFeedbackSubmitScreenFAQClick: return "m_ppro_feedback_submit-screen-faq_click"

// MARK: Duckplayer experiment
case .duckplayerExperimentCohortAssign: return "duckplayer_experiment_cohort_assign"
case .duckplayerExperimentSearch: return "duckplayer_experiment_search"
case .duckplayerExperimentDailySearch: return "duckplayer_experiment_daily_search"
case .duckplayerExperimentWeeklySearch: return "duckplayer_experiment_weekly_search"
case .duckplayerExperimentYoutubePageView: return "duckplayer_experiment_youtube_page_view"
case .duckplayerExperimentCohortAssign: return "duckplayer_experiment_cohort_assign_v2"
case .duckplayerExperimentSearch: return "duckplayer_experiment_search_v2"
case .duckplayerExperimentDailySearch: return "duckplayer_experiment_daily_search_v2"
case .duckplayerExperimentWeeklySearch: return "duckplayer_experiment_weekly_search_v2"
case .duckplayerExperimentYoutubePageView: return "duckplayer_experiment_youtube_page_view_v2"

}
}
Expand Down
66 changes: 33 additions & 33 deletions DuckDuckGo/DuckPlayer/DuckPlayerLaunchExperiment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,19 @@ final class DuckPlayerLaunchExperiment: DuckPlayerLaunchExperimentHandling {
private let dateProvider: DuckPlayerExperimentDateProvider

@UserDefaultsWrapper(key: .duckPlayerPixelExperimentLastWeekPixelFired, defaultValue: nil)
private var lastWeekPixelFired: Int?
private var lastWeekPixelFiredV2: Int?

@UserDefaultsWrapper(key: .duckPlayerPixelExperimentLastDayPixelFired, defaultValue: nil)
private var lastDayPixelFired: Int?
private var lastDayPixelFiredV2: Int?

@UserDefaultsWrapper(key: .duckPlayerPixelExperimentLastVideoIDRendered, defaultValue: nil)
private var lastVideoIDReported: String?
private var lastVideoIDReportedV2: String?

@UserDefaultsWrapper(key: .duckPlayerPixelExperimentEnrollmentDate, defaultValue: nil)
var enrollmentDate: Date?
var enrollmentDateV2: Date?

@UserDefaultsWrapper(key: .duckPlayerPixelExperimentCohort, defaultValue: nil)
var experimentCohort: String?
var experimentCohortV2: String?

private var isInternalUser: Bool

Expand All @@ -113,7 +113,7 @@ final class DuckPlayerLaunchExperiment: DuckPlayerLaunchExperimentHandling {

private var dates: (day: Int, week: Int)? {
guard isEnrolled,
let enrollmentDate = enrollmentDate else { return nil }
let enrollmentDate = enrollmentDateV2 else { return nil }
let currentDate = dateProvider.currentDate
let calendar = Calendar.current
let dayDifference = calendar.dateComponents([.day], from: enrollmentDate, to: currentDate).day ?? 0
Expand All @@ -123,7 +123,7 @@ final class DuckPlayerLaunchExperiment: DuckPlayerLaunchExperimentHandling {

private var formattedEnrollmentDate: String? {
guard isEnrolled,
let enrollmentDate = enrollmentDate else { return nil }
let enrollmentDate = enrollmentDateV2 else { return nil }
return Self.formattedDate(enrollmentDate)
}

Expand All @@ -135,11 +135,11 @@ final class DuckPlayerLaunchExperiment: DuckPlayerLaunchExperimentHandling {
}

var isEnrolled: Bool {
return enrollmentDate != nil && experimentCohort != nil
return enrollmentDateV2 != nil && experimentCohortV2 != nil
}

var isExperimentCohort: Bool {
return experimentCohort == "experiment"
return experimentCohortV2 == "experiment"
}

func assignUserToCohort() {
Expand All @@ -149,32 +149,32 @@ final class DuckPlayerLaunchExperiment: DuckPlayerLaunchExperimentHandling {
if isInternalUser {
cohort = .experiment
}
experimentCohort = cohort.rawValue
enrollmentDate = dateProvider.currentDate
experimentCohortV2 = cohort.rawValue
enrollmentDateV2 = dateProvider.currentDate
fireEnrollmentPixel()
}
}

private func fireEnrollmentPixel() {
guard isEnrolled,
let experimentCohort = experimentCohort,
let experimentCohortV2 = experimentCohortV2,
let formattedEnrollmentDate else { return }

let params = [Constants.variantKey: experimentCohort, Constants.enrollmentKey: formattedEnrollmentDate]
let params = [Constants.variantKey: experimentCohortV2, Constants.enrollmentKey: formattedEnrollmentDate]
pixel.fireDuckPlayerExperimentPixel(pixel: .duckplayerExperimentCohortAssign, withAdditionalParameters: params)
}

func fireSearchPixels() {
if isEnrolled {
guard isEnrolled,
let experimentCohort = experimentCohort,
let experimentCohortV2 = experimentCohortV2,
let dates,
let formattedEnrollmentDate else {
return
}

var params = [
Constants.variantKey: experimentCohort,
Constants.variantKey: experimentCohortV2,
Constants.dayKey: "\(dates.day)",
Constants.enrollmentKey: formattedEnrollmentDate
]
Expand All @@ -183,56 +183,56 @@ final class DuckPlayerLaunchExperiment: DuckPlayerLaunchExperimentHandling {
pixel.fireDuckPlayerExperimentPixel(pixel: .duckplayerExperimentSearch, withAdditionalParameters: params)

// Fire a daily pixel
if dates.day != lastDayPixelFired {
if dates.day != lastDayPixelFiredV2 {
pixel.fireDuckPlayerExperimentPixel(pixel: .duckplayerExperimentDailySearch, withAdditionalParameters: params)
lastDayPixelFired = dates.day
lastDayPixelFiredV2 = dates.day
}

// Fire a weekly pixel
if dates.week != lastWeekPixelFired && dates.day > 0 {
if dates.week != lastWeekPixelFiredV2 && dates.day > 0 {
params.removeValue(forKey: Constants.dayKey)
params[Constants.weekKey] = "\(dates.week)"
pixel.fireDuckPlayerExperimentPixel(pixel: .duckplayerExperimentWeeklySearch, withAdditionalParameters: params)
lastWeekPixelFired = dates.week
lastWeekPixelFiredV2 = dates.week
}
}
}

func fireYoutubePixel(videoID: String) {
guard isEnrolled,
let experimentCohort = experimentCohort,
let experimentCohortV2 = experimentCohortV2,
let dates,
let formattedEnrollmentDate else {
return
}

let params = [
Constants.variantKey: experimentCohort,
Constants.variantKey: experimentCohortV2,
Constants.dayKey: "\(dates.day)",
Constants.stateKey: duckPlayerMode?.stringValue ?? "",
Constants.referrerKey: referrer?.stringValue ?? "",
Constants.enrollmentKey: formattedEnrollmentDate
]
if lastVideoIDReported != videoID {
if lastVideoIDReportedV2 != videoID {
pixel.fireDuckPlayerExperimentPixel(pixel: .duckplayerExperimentYoutubePageView, withAdditionalParameters: params)
lastVideoIDReported = videoID
lastVideoIDReportedV2 = videoID
}
}

func cleanup() {
enrollmentDate = nil
experimentCohort = nil
lastDayPixelFired = nil
lastWeekPixelFired = nil
lastVideoIDReported = nil
enrollmentDateV2 = nil
experimentCohortV2 = nil
lastDayPixelFiredV2 = nil
lastWeekPixelFiredV2 = nil
lastVideoIDReportedV2 = nil
}

func override() {
enrollmentDate = Date()
experimentCohort = "experiment"
lastDayPixelFired = nil
lastWeekPixelFired = nil
lastVideoIDReported = nil
enrollmentDateV2 = Date()
experimentCohortV2 = "experiment"
lastDayPixelFiredV2 = nil
lastWeekPixelFiredV2 = nil
lastVideoIDReportedV2 = nil

}

Expand Down
43 changes: 24 additions & 19 deletions DuckDuckGo/DuckPlayer/DuckPlayerNavigationHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ final class DuckPlayerNavigationHandler {
var featureFlagger: FeatureFlagger
var appSettings: AppSettings
var experiment: DuckPlayerLaunchExperimentHandling
private lazy var internalUserDecider = AppDependencyProvider.shared.internalUserDecider

private struct Constants {
static let SERPURL = "duckduckgo.com/"
Expand Down Expand Up @@ -216,26 +217,30 @@ final class DuckPlayerNavigationHandler {
if let navigationAction, isSERPLink(navigationAction: navigationAction) {
referrer = .serp
}


// DuckPlayer Experiment run
let experiment = DuckPlayerLaunchExperiment(duckPlayerMode: duckPlayerMode, referrer: referrer)

// Enroll user if not enrolled
if !experiment.isEnrolled {
experiment.assignUserToCohort()
}

// DuckPlayer is disabled before user enrolls,
// So trigger a settings change notification
// to let the FE know about the 'actual' setting
// and update Experiment value
if experiment.isExperimentCohort {
duckPlayer.settings.triggerNotification()
experiment.duckPlayerMode = duckPlayer.settings.mode

if featureFlagger.isFeatureOn(.duckPlayer) || internalUserDecider.isInternalUser {

// DuckPlayer Experiment run
let experiment = DuckPlayerLaunchExperiment(duckPlayerMode: duckPlayerMode,
referrer: referrer,
isInternalUser: internalUserDecider.isInternalUser)

// Enroll user if not enrolled
if !experiment.isEnrolled {
experiment.assignUserToCohort()
}

// DuckPlayer is disabled before user enrolls,
// So trigger a settings change notification
// to let the FE know about the 'actual' setting
// and update Experiment value
if experiment.isExperimentCohort {
duckPlayer.settings.triggerNotification()
experiment.duckPlayerMode = duckPlayer.settings.mode
}

experiment.fireYoutubePixel(videoID: videoID)
}

experiment.fireYoutubePixel(videoID: videoID)

}

Expand Down
8 changes: 4 additions & 4 deletions DuckDuckGoTests/DuckPlayerExperimentTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ final class DuckPlayerLaunchExperimentTests: XCTestCase {
sut.assignUserToCohort()

XCTAssertTrue(sut.isEnrolled, "User should be enrolled after assigning to cohort.")
XCTAssertNotNil(sut.experimentCohort, "Experiment cohort should be assigned.")
XCTAssertNotNil(sut.enrollmentDate, "Enrollment date should be set.")
XCTAssertEqual(DuckPlayerLaunchExperiment.formattedDate(sut.enrollmentDate ?? Date()), "20240910", "The assigned date should match.")
XCTAssertNotNil(sut.experimentCohortV2, "Experiment cohort should be assigned.")
XCTAssertNotNil(sut.enrollmentDateV2, "Enrollment date should be set.")
XCTAssertEqual(DuckPlayerLaunchExperiment.formattedDate(sut.enrollmentDateV2 ?? Date()), "20240910", "The assigned date should match.")

// Check the pixel event history
let history = DuckPlayerExperimentPixelFireMock.capturedPixelEventHistory
Expand Down Expand Up @@ -142,7 +142,7 @@ final class DuckPlayerLaunchExperimentTests: XCTestCase {
sut.assignUserToCohort()
XCTAssertEqual(DuckPlayerExperimentPixelFireMock.capturedPixelEventHistory.count, 0, "Enrollment pixel should not have fired again")
XCTAssertEqual(sut.isEnrolled, true, "The assigned date should not change.")
XCTAssertEqual(DuckPlayerLaunchExperiment.formattedDate(sut.enrollmentDate ?? Date()), "20240910", "The assigned date should not change.")
XCTAssertEqual(DuckPlayerLaunchExperiment.formattedDate(sut.enrollmentDateV2 ?? Date()), "20240910", "The assigned date should not change.")
}

func testIfUserIsEnrolled_SearchDailyPixelsFire() {
Expand Down

0 comments on commit fdeb510

Please sign in to comment.