From 3b277fd91fdb1c0b1597857d1315f9eeaf32f2e5 Mon Sep 17 00:00:00 2001 From: "justin.fiedler" Date: Thu, 1 Feb 2024 15:14:17 -0800 Subject: [PATCH] chore: extract isSandboxEnabled into util class for testing, added some tests - WIP --- Amplitude-Swift.xcodeproj/project.pbxproj | 12 ++++++++-- .../contents.xcworkspacedata | 2 +- .../Storages/PersistentStorage.swift | 15 +----------- .../Amplitude/Utilities/SandboxHelper.swift | 21 ++++++++++++++++ .../Storages/PersistentStorageTests.swift | 21 ++++++++++++++++ .../Utilities/SandboxHelperTests.swift | 24 +++++++++++++++++++ 6 files changed, 78 insertions(+), 17 deletions(-) create mode 100644 Sources/Amplitude/Utilities/SandboxHelper.swift create mode 100644 Tests/AmplitudeTests/Utilities/SandboxHelperTests.swift diff --git a/Amplitude-Swift.xcodeproj/project.pbxproj b/Amplitude-Swift.xcodeproj/project.pbxproj index 684d2a0b..9c5bb4b3 100644 --- a/Amplitude-Swift.xcodeproj/project.pbxproj +++ b/Amplitude-Swift.xcodeproj/project.pbxproj @@ -61,6 +61,8 @@ BA994B9D2A4F4FCB00D0913F /* legacy_v4.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = BA994B9B2A4F4B7500D0913F /* legacy_v4.sqlite */; }; BA9BEA4B299FB43B00BC0F7C /* IdentifyInterceptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA9BEA4A299FB43B00BC0F7C /* IdentifyInterceptor.swift */; }; BA9BEA4D299FB4BB00BC0F7C /* IdentifyInterceptorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA9BEA4C299FB4BB00BC0F7C /* IdentifyInterceptorTests.swift */; }; + D010435F2B6C59EE00F8173C /* SandboxHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D010435E2B6C59EE00F8173C /* SandboxHelper.swift */; }; + D01043612B6C5A8500F8173C /* SandboxHelperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01043602B6C5A8500F8173C /* SandboxHelperTests.swift */; }; OBJ_100 /* Mediator.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_21 /* Mediator.swift */; }; OBJ_101 /* AmplitudeDestinationPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_23 /* AmplitudeDestinationPlugin.swift */; }; OBJ_102 /* ContextPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_24 /* ContextPlugin.swift */; }; @@ -123,14 +125,14 @@ isa = PBXContainerItemProxy; containerPortal = OBJ_1 /* Project object */; proxyType = 1; - remoteGlobalIDString = amplitude-swift::Amplitude-Swift; + remoteGlobalIDString = "amplitude-swift::Amplitude-Swift"; remoteInfo = "Amplitude-Swift"; }; 580FD1F1294A56F60036777B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = OBJ_1 /* Project object */; proxyType = 1; - remoteGlobalIDString = amplitude-swift::Amplitude-SwiftTests; + remoteGlobalIDString = "amplitude-swift::Amplitude-SwiftTests"; remoteInfo = "Amplitude-SwiftTests"; }; /* End PBXContainerItemProxy section */ @@ -176,6 +178,8 @@ BA994B9B2A4F4B7500D0913F /* legacy_v4.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; path = legacy_v4.sqlite; sourceTree = ""; }; BA9BEA4A299FB43B00BC0F7C /* IdentifyInterceptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentifyInterceptor.swift; sourceTree = ""; }; BA9BEA4C299FB4BB00BC0F7C /* IdentifyInterceptorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentifyInterceptorTests.swift; sourceTree = ""; }; + D010435E2B6C59EE00F8173C /* SandboxHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SandboxHelper.swift; sourceTree = ""; }; + D01043602B6C5A8500F8173C /* SandboxHelperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SandboxHelperTests.swift; sourceTree = ""; }; OBJ_10 /* ConsoleLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleLogger.swift; sourceTree = ""; }; OBJ_11 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; OBJ_12 /* EventBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBridge.swift; sourceTree = ""; }; @@ -394,6 +398,7 @@ OBJ_52 /* UrlExtension.swift */, BA9BEA4A299FB43B00BC0F7C /* IdentifyInterceptor.swift */, 8EDEC54AB4DF9E1074C3D6A4 /* Weak.swift */, + D010435E2B6C59EE00F8173C /* SandboxHelper.swift */, ); path = Utilities; sourceTree = ""; @@ -499,6 +504,7 @@ OBJ_74 /* UrlExtensionTests.swift */, BA9BEA4C299FB4BB00BC0F7C /* IdentifyInterceptorTests.swift */, 8EDEC4F83BFAA664749FAEF0 /* QueueTimeTests.swift */, + D01043602B6C5A8500F8173C /* SandboxHelperTests.swift */, ); path = Utilities; sourceTree = ""; @@ -640,6 +646,7 @@ OBJ_154 /* TypesTests.swift in Sources */, OBJ_155 /* EventPipelineTests.swift in Sources */, OBJ_156 /* HttpClientTests.swift in Sources */, + D01043612B6C5A8500F8173C /* SandboxHelperTests.swift in Sources */, OBJ_157 /* PersistentStorageResponseHandlerTests.swift in Sources */, OBJ_158 /* UrlExtensionTests.swift in Sources */, 8EDEC4EE0DE1C89889F451B5 /* QueueTimeTests.swift in Sources */, @@ -698,6 +705,7 @@ 8EDEC8F8DD2CDCD6568512F8 /* RemnantDataMigration.swift in Sources */, 8EDEC977C03AA2676724F436 /* BasePlugins.swift in Sources */, 8EDEC1073A308B12B5CCD975 /* AnalyticsConnectorPlugin.swift in Sources */, + D010435F2B6C59EE00F8173C /* SandboxHelper.swift in Sources */, 8EDEC3283B812D5D34DADF7B /* AnalyticsConnectorIdentityPlugin.swift in Sources */, 8EDEC4D0C0CE07BF211804CC /* DefaultTrackingOptions.swift in Sources */, 8EDEC30C0075E9D92B1B5210 /* UIKitScreenViews.swift in Sources */, diff --git a/Amplitude-Swift.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Amplitude-Swift.xcodeproj/project.xcworkspace/contents.xcworkspacedata index fe1aa713..919434a6 100644 --- a/Amplitude-Swift.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/Amplitude-Swift.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,4 @@ - \ No newline at end of file + diff --git a/Sources/Amplitude/Storages/PersistentStorage.swift b/Sources/Amplitude/Storages/PersistentStorage.swift index cb245eed..34fab1a2 100644 --- a/Sources/Amplitude/Storages/PersistentStorage.swift +++ b/Sources/Amplitude/Storages/PersistentStorage.swift @@ -238,22 +238,10 @@ extension PersistentStorage { return result } - private func isSandboxEnabled() -> Bool { - let environment = ProcessInfo.processInfo.environment - return environment["APP_SANDBOX_CONTAINER_ID"] != nil - } - internal func getEventsStorageDirectory(createDirectory: Bool = true) -> URL { let searchPathDirectory = FileManager.SearchPathDirectory.applicationSupportDirectory - // Make sure Amplitude data is sandboxed per app - #if os(iOS) - // iOS is sandboxed by default - let appPath = "" - #else - // macOS/tvOS are not sandboxed automatically - let appPath = isSandboxEnabled() ? "" : "\(Bundle.main.bundleIdentifier!)/" - #endif + let appPath = SandboxHelper.isSandboxEnabled() ? "" : "\(Bundle.main.bundleIdentifier!)/" let urls = fileManager.urls(for: searchPathDirectory, in: .userDomainMask) let docUrl = urls[0] @@ -267,7 +255,6 @@ extension PersistentStorage { at: storageUrl, withIntermediateDirectories: true, attributes: nil) try? storageUrl.setResourceValues(values) } - return storageUrl } diff --git a/Sources/Amplitude/Utilities/SandboxHelper.swift b/Sources/Amplitude/Utilities/SandboxHelper.swift new file mode 100644 index 00000000..51dfc2f5 --- /dev/null +++ b/Sources/Amplitude/Utilities/SandboxHelper.swift @@ -0,0 +1,21 @@ +// +// SandboxHelper.swift +// Amplitude-Swift +// +// Created by Justin Fiedler on 2/1/24. +// + +import Foundation + +public class SandboxHelper { + static public func isSandboxEnabled() -> Bool { + #if os(iOS) + // iOS is always sandboxed + return true + #else + // this works on macOS (not iOS), need to test on tvOS + let environment = ProcessInfo.processInfo.environment + return environment["APP_SANDBOX_CONTAINER_ID"] != nil + #endif + } +} diff --git a/Tests/AmplitudeTests/Storages/PersistentStorageTests.swift b/Tests/AmplitudeTests/Storages/PersistentStorageTests.swift index 5cf457c6..3742a43a 100644 --- a/Tests/AmplitudeTests/Storages/PersistentStorageTests.swift +++ b/Tests/AmplitudeTests/Storages/PersistentStorageTests.swift @@ -49,4 +49,25 @@ final class PersistentStorageTests: XCTestCase { XCTAssertNotEqual(eventFiles?[0].pathExtension, PersistentStorage.TEMP_FILE_EXTENSION) persistentStorage.reset() } + + func testStorageDirectorySandboxed() { + let persistentStorage = PersistentStorage(storagePrefix: "sandbox-instance") + + // e.g. /Library/Developer/CoreSimulator/Devices/AA0CFF70-35A4-4D85-AB9A-C27A8DBF94D7/data/Library/Application%20Support/amplitude/amplitude-swift-sandbox-instance.events.inde + // /Library/Developer/CoreSimulator/Devices/AA0CFF70-35A4-4D85-AB9A-C27A8DBF94D7/data/Containers/Data/Application/06213CC5-0BE3-4822-BF6A-44C711467CB7/Library/Application%20Support/amplitude/amplitude-swift-identify-default_instance.events.index + let iOSSandboxPathRegex = "CoreSimulator/Devices/[A-Z0-9-]*/data/" + let bundleId = Bundle.main.bundleIdentifier! + + let storageUrl = persistentStorage.getEventsStorageDirectory(createDirectory: false) + + // print("bundleId=\(bundleId)") + // print("storageUrl=\(storageUrl)") + + #if os(iOS) + XCTAssertNotNil(storageUrl.absoluteString.range(of: iOSSandboxPathRegex, options: .regularExpression, range: nil, locale: nil)) + #else + XCTAssertEqual(storageUrl.absoluteString.contains(bundleId), true) + #endif + persistentStorage.reset() + } } diff --git a/Tests/AmplitudeTests/Utilities/SandboxHelperTests.swift b/Tests/AmplitudeTests/Utilities/SandboxHelperTests.swift new file mode 100644 index 00000000..c27dbf51 --- /dev/null +++ b/Tests/AmplitudeTests/Utilities/SandboxHelperTests.swift @@ -0,0 +1,24 @@ +// +// SandboxHelperTests.swift +// Amplitude-SwiftTests +// +// Created by Justin Fiedler on 2/1/24. +// + +import XCTest + +@testable import AmplitudeSwift + +final class SandboxHelperTests: XCTestCase { + + func testIsSandboxEnabled() { + let isSandboxed = SandboxHelper.isSandboxEnabled() + + #if os(iOS) + XCTAssertEqual(isSandboxed, true) + #else + XCTAssertEqual(isSandboxed, false) + #endif + } + +}