diff --git a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Model/Actions/Click.swift b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Model/Actions/Click.swift index a75fe0113f..e237d32bfb 100644 --- a/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Model/Actions/Click.swift +++ b/LocalPackages/DataBrokerProtection/Sources/DataBrokerProtection/Model/Actions/Click.swift @@ -18,9 +18,73 @@ import Foundation +struct Condition: Codable, Sendable { + let left: String + let operation: String + let right: String +} + +struct Choice: Codable, Sendable { + let condition: Condition + let elements: [PageElement] +} + struct ClickAction: Action { let id: String let actionType: ActionType - let elements: [PageElement] + let elements: [PageElement]? let dataSource: DataSource? + let choices: [Choice]? + let `default`: Default? + + let hasDefault: Bool + + struct Default: Codable { + let elements: [PageElement]? + } + + init(id: String, actionType: ActionType, elements: [PageElement]? = nil, dataSource: DataSource? = nil, choices: [Choice]? = nil, `default`: Default? = nil, hasDefault: Bool = false) { + self.id = id + self.actionType = actionType + self.elements = elements + self.dataSource = dataSource + self.choices = choices + self.default = `default` + self.hasDefault = `default` != nil + } + + init(from decoder: any Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.id = try container.decode(String.self, forKey: .id) + self.actionType = try container.decode(ActionType.self, forKey: .actionType) + self.elements = try container.decodeIfPresent([PageElement].self, forKey: .elements) + self.dataSource = try container.decodeIfPresent(DataSource.self, forKey: .dataSource) + self.choices = try container.decodeIfPresent([Choice].self, forKey: .choices) + self.default = try container.decodeIfPresent(Default.self, forKey: .default) + self.hasDefault = container.contains(.default) + } + + enum CodingKeys: String, CodingKey { + case id + case actionType + case elements + case dataSource + case choices + case `default` + } + + func encode(to encoder: any Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(self.id, forKey: .id) + try container.encode(self.actionType, forKey: .actionType) + try container.encodeIfPresent(self.elements, forKey: .elements) + try container.encodeIfPresent(self.dataSource, forKey: .dataSource) + try container.encodeIfPresent(self.choices, forKey: .choices) + + if self.hasDefault { + try container.encode(self.default, forKey: .default) + } else { + try container.encodeNil(forKey: .default) + } + } } diff --git a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerOperationActionTests.swift b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerOperationActionTests.swift index cc14f56b56..e5c816432c 100644 --- a/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerOperationActionTests.swift +++ b/LocalPackages/DataBrokerProtection/Tests/DataBrokerProtectionTests/DataBrokerOperationActionTests.swift @@ -394,7 +394,7 @@ final class DataBrokerOperationActionTests: XCTestCase { func testWhenClickActionRuns_thenStageIsSetToSubmit() async { let mockStageCalculator = MockStageDurationCalculator() - let clickAction = ClickAction(id: "1", actionType: .click, elements: [PageElement](), dataSource: nil) + let clickAction = ClickAction(id: "1", actionType: .click, elements: [PageElement](), dataSource: nil, choices: nil, default: nil, hasDefault: false) let sut = OptOutJob( privacyConfig: PrivacyConfigurationManagingMock(), prefs: ContentScopeProperties.mock,