blob: 2bd31b589a9de01cd2285cce52fecf13ad3ef04a [file] [edit]
// Copyright (C) 2026 Apple Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
import Foundation
private import TestWebKitAPILibrary.Helpers.cocoa.SafeBrowsingTestUtilities
import struct Swift.String
/// Namespaced Safe Browsing filter lists, keyed by `"<namespace>/domains"` and `"<namespace>/filter"`.
public typealias SafeBrowsingLists = [String: [String]]
/// Replaces the namespaced list lookup on `SSBLookupContext` for the duration of the given closure.
///
/// - Parameters:
/// - lists: The lists the stubbed lookup should report.
/// - body: The work to run while the stub is in effect.
/// - Returns: The value returned by `body`.
/// - Throws: Rethrows any error thrown by `body`.
@MainActor
@discardableResult
public func withStubbedSafeBrowsingLists<Result: ~Copyable, Failure: Error>(
_ lists: SafeBrowsingLists,
perform body: nonisolated(nonsending) () async throws(Failure) -> sending Result
) async throws(Failure) -> sending Result {
typealias LookUpListsBlock =
@convention(block) (
AnyObject, String?, String?, @escaping @Sendable (SafeBrowsingLists?, (any Error)?) -> Void
) -> Void
let lookUpLists: LookUpListsBlock = { _, _, _, completionHandler in
Task.detached {
completionHandler(lists, nil)
}
}
return try await withSwizzledObjectiveCInstanceMethod(
replacing: testSSBLookupContextClass(),
name: Selector(("_getListsForNamespace:collectionId:completionHandler:")),
with: lookUpLists
) { () throws(Failure) in
try await body()
}
}
/// Replaces `+[SSBLookupContext sharedLookupContext]` for the duration of the given closure.
///
/// - Parameters:
/// - lookupContext: The stand-in to return, such as `TestLookupContext.shared()`.
/// - body: The work to run while the stub is in effect.
/// - Returns: The value returned by `body`.
/// - Throws: Rethrows any error thrown by `body`.
@MainActor
@discardableResult
public func withStubbedSharedLookupContext<Result: ~Copyable, Failure: Error>(
_ lookupContext: AnyObject,
perform body: nonisolated(nonsending) () async throws(Failure) -> sending Result
) async throws(Failure) -> sending Result {
typealias SharedLookupContextBlock = @convention(block) (AnyObject) -> AnyObject
let sharedLookupContext: SharedLookupContextBlock = { _ in lookupContext }
return try await withSwizzledObjectiveCClassMethod(
class: testSSBLookupContextClass(),
replacing: #selector(TestLookupContext.shared),
with: sharedLookupContext
) { () throws(Failure) in
try await body()
}
}