Skip to content

Commit

Permalink
Addressing PR suggestions:
Browse files Browse the repository at this point in the history
- unit tests
- file prefix
  • Loading branch information
todd-spruceid committed Aug 6, 2024
1 parent a4a444b commit d1bb7cc
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 41 deletions.
106 changes: 65 additions & 41 deletions Sources/MobileSdk/StorageManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,31 @@
//

import Foundation
import SpruceIDMobileSdkRs

// import SpruceIDMobileSdkRs

// The following is a stripped-down version of the protocol definition from mobile-sdk-rs against which the storage
// manager is intended to link.

/*
public typealias Key = String
public typealias Value = Data
public typealias Key = String
public typealias Value = Data

public enum StorageManagerError: Error {
case InvalidLookupKey
case CouldNotDecryptValue
case StorageFull
case CouldNotMakeKey
case InternalError
}

public protocol StorageManagerInterface : AnyObject {
func add(key: Key, value: Value) throws
func get(key: Key) throws -> Value
func list() -> [Key]
func remove(key: Key) throws
}
*/
public protocol StorageManagerInterface: AnyObject {
func add(key: Key, value: Value) throws
func get(key: Key) throws -> Value
func list() -> [Key]
func remove(key: Key) throws
}
*/

//
// Code
Expand All @@ -48,14 +57,32 @@ class StorageManager: NSObject, StorageManagerInterface {
// Get the applications support dir, and tack the name of the thing we're storing on the end of it. This does
// imply that `file` should be a valid filename.

let asdir = try FileManager.default.url(for: .applicationSupportDirectory,
in: .userDomainMask,
appropriateFor: nil, // Ignored
create: true) // May not exist, make if necessary.
let fm = FileManager.default
let bundle = Bundle.main

let asdir = try fm.url(for: .applicationSupportDirectory,
in: .userDomainMask,
appropriateFor: nil, // Ignored
create: true) // May not exist, make if necessary.

// If we create subdirectories in the application support directory, we need to put them in a subdir named
// after the app; normally, that's `CFBundleDisplayName` from `info.plist`, but that key doesn't have to be
// set, in which case we need to use `CFBundleName`.

guard let appname = bundle.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String ??
bundle.object(forInfoDictionaryKey: "CFBundleName") as? String
else {
return nil
}

let datadir = asdir.appending(path: "\(appname)/sprucekit/datastore/", directoryHint: .isDirectory)

if !fm.fileExists(atPath: datadir.path) {
try fm.createDirectory(at: datadir, withIntermediateDirectories: true, attributes: nil)
}

return asdir.appendingPathComponent(file)
} catch { // Did the attempt to get the application support dir fail?
print("Failed to get/create the application support dir.")
return datadir.appendingPathComponent(file)
} catch {
return nil
}
}
Expand All @@ -76,8 +103,7 @@ class StorageManager: NSObject, StorageManagerInterface {
do {
try value.write(to: file, options: .completeFileProtection)
} catch {
print("Failed to write the data for '\(key)'.")
return
throw StorageManagerError.InternalError
}
}

Expand All @@ -97,10 +123,8 @@ class StorageManager: NSObject, StorageManagerInterface {
let d = try Data(contentsOf: file)
return d
} catch {
print("Failed to read '\(file)'.")
throw StorageManagerError.InternalError
}

return Data()
}

// Method: list()
Expand Down Expand Up @@ -143,45 +167,45 @@ class StorageManager: NSObject, StorageManagerInterface {
// Check to see if everything works.

/*
func sys_test() {
let key = "test_key"
func sys_test() {
let key = "test_key"
let value = Data("Some random string of text. 😎".utf8)

do {
try add(key: key, value: value)
try add(key: key, value: value)
} catch {
print("\(self.classForCoder):\(#function): Failed add() value for key.")
return
print("\(classForCoder):\(#function): Failed add() value for key.")
return
}

let keys = list();
let keys = list()

print("Keys:")
for k in keys {
print(" \(k)")
print(" \(k)")
}

do {
let payload = try get(key: key)
let payload = try get(key: key)

if !(payload == value) {
print("\(self.classForCoder):\(#function): Mismatch between stored & retrieved value.")
return
}
if !(payload == value) {
print("\(classForCoder):\(#function): Mismatch between stored & retrieved value.")
return
}
} catch {
print("\(self.classForCoder):\(#function): Failed get() value for key.")
return
print("\(classForCoder):\(#function): Failed get() value for key.")
return
}

do {
try remove(key: key)
try remove(key: key)
} catch {
print("\(self.classForCoder):\(#function): Failed remove() value for key.")
return
print("\(classForCoder):\(#function): Failed remove() value for key.")
return
}

print("\(self.classForCoder):\(#function): Completed successfully.")
}
print("\(classForCoder):\(#function): Completed successfully.")
}
*/
}

Expand Down
17 changes: 17 additions & 0 deletions Tests/MobileSdkTests/StorageManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@testable import SpruceIDMobileSdk
import XCTest

final class StorageManager: XCTestCase {
func storage_test() throws {
let key = "test_key"
let value = Data("Some random string of text. 😎".utf8)

XTCAssertNoThrow(add(key: key, value: value), "\(classForCoder):\(#function): Failed add() value for key.")

try XTCAssertNoThrow(let payload = get(key: key), "\(classForCoder):\(#function): Failed get() value for key.")

XTCAssert(payload == value, "\(classForCoder):\(#function): Mismatch between stored & retrieved value.")

try XTCAssertNoThrow(remove(key: key), "\(classForCoder):\(#function): Failed remove() value for key.")
}
}

0 comments on commit d1bb7cc

Please sign in to comment.