Skip to content
24 changes: 22 additions & 2 deletions Jamf Sync.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
840A79092ACD9B0A00161D85 /* ConfirmationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840A79082ACD9B0A00161D85 /* ConfirmationView.swift */; };
8412279F2BEADBB20097B83E /* XmlErrorParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8412279E2BEADBB20097B83E /* XmlErrorParser.swift */; };
841227A12BEADD6E0097B83E /* XmlErrorParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841227A02BEADD6E0097B83E /* XmlErrorParserTests.swift */; };
41E403B4E163AE45FD580F6E /* ArgumentParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C54B369474FC396199FB982 /* ArgumentParserTests.swift */; };
841DE9D92BA395900092DBE7 /* Jamf Sync User Guide.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 841DE9D82BA395900092DBE7 /* Jamf Sync User Guide.pdf */; };
8422B1212F6494FD0019C2DE /* CommandLineProcessingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CMDLINE123456789ABCDEF0 /* CommandLineProcessingTests.swift */; };
8422B1222F649B8B0019C2DE /* TemporaryFileManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = TEMPFILE123456789ABCDEF0 /* TemporaryFileManagerTests.swift */; };
Expand All @@ -31,6 +32,9 @@
846499CF2B630D7700A8EA7B /* FolderDpTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846499CE2B630D7700A8EA7B /* FolderDpTests.swift */; };
846499D12B631B6A00A8EA7B /* MockFileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846499D02B631B6A00A8EA7B /* MockFileManager.swift */; };
846499D32B64165E00A8EA7B /* TestErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846499D22B64165E00A8EA7B /* TestErrors.swift */; };
63F41799AC5DE918435399D1 /* ChecksumsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D89812BAC4405E98A15D1CCB /* ChecksumsTests.swift */; };
2AD32CC765B804C67356E7F4 /* GeneralCloudDpTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20024D5A84FE240AE8C05324 /* GeneralCloudDpTests.swift */; };
1FE12F34F420D4E74BE3E1B9 /* Jcds2DpAdditionalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B0BB8F2E75BB97315FCFFDE /* Jcds2DpAdditionalTests.swift */; };
846499D52B64268A00A8EA7B /* DistributionPointTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846499D42B64268A00A8EA7B /* DistributionPointTests.swift */; };
846499DE2B699F8E00A8EA7B /* MockDistributionPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846499DD2B699F8E00A8EA7B /* MockDistributionPoint.swift */; };
846499E02B699FB500A8EA7B /* MockJamfProInstance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846499DF2B699FB500A8EA7B /* MockJamfProInstance.swift */; };
Expand All @@ -46,6 +50,7 @@
848C2D282BC48A3800036999 /* GeneralCloudDp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848C2D272BC48A3800036999 /* GeneralCloudDp.swift */; };
849809DB2CB8575B001F94C9 /* UploadTimeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849809DA2CB8575B001F94C9 /* UploadTimeTests.swift */; };
849FC3412BD06A43008BAC02 /* VersionInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849FC3402BD06A43008BAC02 /* VersionInfo.swift */; };
9E5386D659B8B8403D02E32F /* TestingUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC5A5F6388C187307AD3EBCC /* TestingUtility.swift */; };
84AB59C52B20D569007333AD /* CloudSessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AB59C42B20D569007333AD /* CloudSessionDelegate.swift */; };
84B967642B74157C00D73F75 /* HelpMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B967632B74157C00D73F75 /* HelpMenu.swift */; };
84BA65E32AD057E10058D291 /* SavableItems.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84BA65E22AD057E10058D291 /* SavableItems.swift */; };
Expand Down Expand Up @@ -127,6 +132,7 @@

/* Begin PBXFileReference section */
1829A6AA7D2850AF23277749 /* FileManagerMoveRetainingPermissionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManagerMoveRetainingPermissionsTests.swift; sourceTree = "<group>"; };
3C54B369474FC396199FB982 /* ArgumentParserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArgumentParserTests.swift; sourceTree = "<group>"; };
4154F4CC0D4B5B8025ECF9D1 /* FileHashTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileHashTests.swift; sourceTree = "<group>"; };
840A79002ACB6E8200161D85 /* SaveableItemListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SaveableItemListView.swift; sourceTree = "<group>"; };
840A79022ACB75FC00161D85 /* SavableItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavableItem.swift; sourceTree = "<group>"; };
Expand All @@ -151,6 +157,9 @@
846499CE2B630D7700A8EA7B /* FolderDpTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FolderDpTests.swift; sourceTree = "<group>"; };
846499D02B631B6A00A8EA7B /* MockFileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockFileManager.swift; sourceTree = "<group>"; };
846499D22B64165E00A8EA7B /* TestErrors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestErrors.swift; sourceTree = "<group>"; };
D89812BAC4405E98A15D1CCB /* ChecksumsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChecksumsTests.swift; sourceTree = "<group>"; };
20024D5A84FE240AE8C05324 /* GeneralCloudDpTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralCloudDpTests.swift; sourceTree = "<group>"; };
7B0BB8F2E75BB97315FCFFDE /* Jcds2DpAdditionalTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Jcds2DpAdditionalTests.swift; sourceTree = "<group>"; };
846499D42B64268A00A8EA7B /* DistributionPointTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DistributionPointTests.swift; sourceTree = "<group>"; };
846499DD2B699F8E00A8EA7B /* MockDistributionPoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockDistributionPoint.swift; sourceTree = "<group>"; };
846499DF2B699FB500A8EA7B /* MockJamfProInstance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockJamfProInstance.swift; sourceTree = "<group>"; };
Expand All @@ -167,6 +176,7 @@
848C2D272BC48A3800036999 /* GeneralCloudDp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralCloudDp.swift; sourceTree = "<group>"; };
849809DA2CB8575B001F94C9 /* UploadTimeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploadTimeTests.swift; sourceTree = "<group>"; };
849FC3402BD06A43008BAC02 /* VersionInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionInfo.swift; sourceTree = "<group>"; };
FC5A5F6388C187307AD3EBCC /* TestingUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestingUtility.swift; sourceTree = "<group>"; };
84AB59C42B20D569007333AD /* CloudSessionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudSessionDelegate.swift; sourceTree = "<group>"; };
84B967632B74157C00D73F75 /* HelpMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelpMenu.swift; sourceTree = "<group>"; };
84BA65E22AD057E10058D291 /* SavableItems.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavableItems.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -263,9 +273,12 @@
8422AF622F60846E0019C2DE /* Model */ = {
isa = PBXGroup;
children = (
D89812BAC4405E98A15D1CCB /* ChecksumsTests.swift */,
846499D42B64268A00A8EA7B /* DistributionPointTests.swift */,
846499E12B6AA7C300A8EA7B /* FileShareDpTests.swift */,
846499CE2B630D7700A8EA7B /* FolderDpTests.swift */,
20024D5A84FE240AE8C05324 /* GeneralCloudDpTests.swift */,
7B0BB8F2E75BB97315FCFFDE /* Jcds2DpAdditionalTests.swift */,
846499E72B6BFCA900A8EA7B /* Jcds2DpTests.swift */,
846499E32B6B080B00A8EA7B /* SynchronizeTaskTests.swift */,
);
Expand All @@ -275,11 +288,12 @@
8422B1232F64AE9B0019C2DE /* Utility */ = {
isa = PBXGroup;
children = (
3C54B369474FC396199FB982 /* ArgumentParserTests.swift */,
CMDLINE123456789ABCDEF0 /* CommandLineProcessingTests.swift */,
TEMPFILE123456789ABCDEF0 /* TemporaryFileManagerTests.swift */,
841227A02BEADD6E0097B83E /* XmlErrorParserTests.swift */,
4154F4CC0D4B5B8025ECF9D1 /* FileHashTests.swift */,
1829A6AA7D2850AF23277749 /* FileManagerMoveRetainingPermissionsTests.swift */,
TEMPFILE123456789ABCDEF0 /* TemporaryFileManagerTests.swift */,
841227A02BEADD6E0097B83E /* XmlErrorParserTests.swift */,
);
path = Utility;
sourceTree = "<group>";
Expand Down Expand Up @@ -448,6 +462,7 @@
84FC41652AD895F400DCB033 /* KeychainHelper.swift */,
8468917D2BCEC4BB00B9FCA4 /* OutputStream_write.swift */,
84BF5E392CC15FB4008B07A1 /* TemporaryFileManager.swift */,
FC5A5F6388C187307AD3EBCC /* TestingUtility.swift */,
84DD583A2BC5C2A700E8DA23 /* URL+isDirectory.swift */,
84E489982B5AC80600FFFE59 /* UserSettings.swift */,
849FC3402BD06A43008BAC02 /* VersionInfo.swift */,
Expand Down Expand Up @@ -673,6 +688,7 @@
840A79012ACB6E8200161D85 /* SaveableItemListView.swift in Sources */,
84BC6E492AC380FD00CF6D39 /* FolderView.swift in Sources */,
849FC3412BD06A43008BAC02 /* VersionInfo.swift in Sources */,
9E5386D659B8B8403D02E32F /* TestingUtility.swift in Sources */,
84E489992B5AC80600FFFE59 /* UserSettings.swift in Sources */,
84BC6E472AC380D200CF6D39 /* JamfProServerView.swift in Sources */,
8412279F2BEADBB20097B83E /* XmlErrorParser.swift in Sources */,
Expand Down Expand Up @@ -730,12 +746,16 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
41E403B4E163AE45FD580F6E /* ArgumentParserTests.swift in Sources */,
8422B1252F64B50E0019C2DE /* FileHashTests.swift in Sources */,
841227A12BEADD6E0097B83E /* XmlErrorParserTests.swift in Sources */,
846499E02B699FB500A8EA7B /* MockJamfProInstance.swift in Sources */,
846499DE2B699F8E00A8EA7B /* MockDistributionPoint.swift in Sources */,
63F41799AC5DE918435399D1 /* ChecksumsTests.swift in Sources */,
8422B1212F6494FD0019C2DE /* CommandLineProcessingTests.swift in Sources */,
846499D52B64268A00A8EA7B /* DistributionPointTests.swift in Sources */,
2AD32CC765B804C67356E7F4 /* GeneralCloudDpTests.swift in Sources */,
1FE12F34F420D4E74BE3E1B9 /* Jcds2DpAdditionalTests.swift in Sources */,
846499E42B6B080B00A8EA7B /* SynchronizeTaskTests.swift in Sources */,
846499E82B6BFCA900A8EA7B /* Jcds2DpTests.swift in Sources */,
846499E22B6AA7C300A8EA7B /* FileShareDpTests.swift in Sources */,
Expand Down
3 changes: 3 additions & 0 deletions JamfSync/Model/FileShareDp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ class FileShareDp: DistributionPoint {
}

private func loadKeychainData() {
// Skip keychain access during tests
guard !TestingUtility.isRunningTests else { return }

guard let address, let readWriteUsername else { return }
let keychainHelper = KeychainHelper()
var serviceName = keychainHelper.fileShareServiceName(username: readWriteUsername, urlString: address)
Expand Down
3 changes: 3 additions & 0 deletions JamfSync/Model/JamfProInstance.swift
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,9 @@ class JamfProInstance: SavableItem {

/// Loads data from the keychain
func loadKeychainData() async {
// Skip keychain access during tests
guard !TestingUtility.isRunningTests else { return }

guard let urlHost = url?.host(), !usernameOrClientId.isEmpty else { return }
let keychainHelper = KeychainHelper()
let serviceName = keychainHelper.jamfProServiceName(urlString: urlHost)
Expand Down
14 changes: 12 additions & 2 deletions JamfSync/Utility/ArgumentParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ArgumentParser: NSObject {

fileprivate func processStringArg(_ i: inout Int) -> String? {
var stringArg: String?
if i < CommandLine.arguments.count - 1 {
if i < arguments.count - 1 {
stringArg = arguments[i + 1]
i = i + 1
}
Expand Down Expand Up @@ -119,7 +119,17 @@ class ArgumentParser: NSObject {

func validateArgs() -> Bool {
// Either none or both, but not one or the other
if (srcDp == nil && dstDp == nil) || (srcDp != nil && dstDp != nil) {
if srcDp == nil && dstDp == nil {
// If both are nil but arguments were passed, that's an error
// (e.g., -s without a value)
if someArgumentsPassed {
print("Both the source and the destination arguments are required.")
print("")
displayHelp()
return false
}
return true
} else if srcDp != nil && dstDp != nil {
return true
} else {
print("Both the source and the destination arguments are required.")
Expand Down
12 changes: 12 additions & 0 deletions JamfSync/Utility/TestingUtility.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// Copyright 2024, Jamf
//

import Foundation

struct TestingUtility {
static var isRunningTests: Bool {
return ProcessInfo.processInfo.environment["XCTestConfigurationFilePath"] != nil ||
NSClassFromString("XCTestCase") != nil
}
}
5 changes: 5 additions & 0 deletions JamfSyncTests/Mocks/MockFileManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class MockFileManager: FileManager {
var fileExistsResponseProvider: ((String, UnsafeMutablePointer<ObjCBool>?) -> Bool)?
var directoryCreated: URL?
var createDirectoryError: Error?
var attributesSet: [String: [FileAttributeKey: Any]] = [:]

override func contentsOfDirectory(at url: URL, includingPropertiesForKeys keys: [URLResourceKey]?, options mask: FileManager.DirectoryEnumerationOptions = []) throws -> [URL] {
if let contentsOfDirectoryError {
Expand Down Expand Up @@ -88,4 +89,8 @@ class MockFileManager: FileManager {
}
directoryCreated = url
}

override func setAttributes(_ attributes: [FileAttributeKey : Any], ofItemAtPath path: String) throws {
attributesSet[path] = attributes
}
}
Loading
Loading