Fix api call creation

sync2
Laurent 9 months ago
parent be67b229e0
commit 2b26950d67
  1. 35
      LeStorage/ApiCallCollection.swift
  2. 85
      LeStorageTests/ApiCallTests.swift

@ -216,15 +216,38 @@ actor ApiCallCollection<T: Storable>: SomeCallCollection {
/// Returns an APICall instance for the Storable [instance] and an HTTP [method]
/// The method updates existing calls or creates a new one
fileprivate func _callForInstance(_ instance: T, method: HTTPMethod) async throws -> ApiCall<T>? {
func callForInstance(_ instance: T, method: HTTPMethod) throws -> ApiCall<T>? {
// cleanup
let existingCalls = self.items.filter { $0.dataId == instance.stringId }
self._deleteCalls(existingCalls)
if existingCalls.count > 1 {
StoreCenter.main.log(message: "There are multiple calls registered for a single item: \(T.resourceName()), id = \(instance.stringId)")
}
let currentHTTPMethod = existingCalls.first?.method
var call: ApiCall<T>? = nil
if let currentHTTPMethod {
switch (currentHTTPMethod, method) {
case (.post, .put):
call = try self._createCall(instance, method: .post)
case (.post, .delete):
self._deleteCalls(existingCalls)
return nil
case (.put, .put):
call = try self._createCall(instance, method: .put)
case (.put, .delete):
call = try self._createCall(instance, method: .delete)
default:
StoreCenter.main.log(message: "case \(currentHTTPMethod) / \(method) should not happen")
}
} else {
call = try self._createCall(instance, method: method)
}
if let call {
self._deleteCalls(existingCalls)
self._prepareCall(apiCall: call)
}
// create
let call = try self._createCall(instance, method: method)
self._prepareCall(apiCall: call)
return call
}
@ -291,7 +314,7 @@ actor ApiCallCollection<T: Storable>: SomeCallCollection {
/// Initiates the process of sending the data with the server
fileprivate func _synchronize<V: Decodable>(_ instance: T, method: HTTPMethod) async throws -> V? {
if let apiCall = try await self._callForInstance(instance, method: method) {
if let apiCall = try self.callForInstance(instance, method: method) {
return try await self._executeApiCall(apiCall)
} else {
return nil

@ -0,0 +1,85 @@
//
// ApiCallTests.swift
// LeStorageTests
//
// Created by Laurent Morvillier on 15/02/2025.
//
import Testing
@testable import LeStorage
class Thing: ModelObject, Storable {
static func resourceName() -> String { return "thing" }
static func tokenExemptedMethods() -> [LeStorage.HTTPMethod] { return [] }
static func filterByStoreIdentifier() -> Bool { return false }
var id: String = Store.randomId()
var name: String
init(name: String) {
self.name = name
}
}
struct ApiCallTests {
@Test func testApiCallProvisioning1() async throws {
let collection = ApiCallCollection<Thing>()
let thing = Thing(name: "yeah")
let _ = try await collection.sendInsertion(thing)
await #expect(collection.items.count == 1)
if let apiCall = await collection.items.first {
#expect(apiCall.method == .post)
}
thing.name = "woo"
let _ = try await collection.sendUpdate(thing)
await #expect(collection.items.count == 1)
if let apiCall = await collection.items.first {
#expect(apiCall.method == .post)
}
let _ = try await collection.sendDeletion(thing)
await #expect(collection.items.count == 0)
}
@Test func testApiCallProvisioning2() async throws {
let collection = ApiCallCollection<Thing>()
let thing = Thing(name: "yeah")
let _ = try await collection.sendUpdate(thing)
await #expect(collection.items.count == 1)
if let apiCall = await collection.items.first {
#expect(apiCall.method == .put)
}
thing.name = "woo"
let _ = try await collection.sendUpdate(thing)
await #expect(collection.items.count == 1)
if let apiCall = await collection.items.first {
#expect(apiCall.method == .put)
}
let _ = try await collection.sendDeletion(thing)
await #expect(collection.items.count == 1)
}
@Test func testApiCallProvisioning3() async throws {
let collection = ApiCallCollection<Thing>()
let thing = Thing(name: "yeah")
let _ = try await collection.sendDeletion(thing)
await #expect(collection.items.count == 1)
let _ = try await collection.sendDeletion(thing)
await #expect(collection.items.count == 1)
let _ = try await collection.sendDeletion(thing)
await #expect(collection.items.count == 1)
}
}
Loading…
Cancel
Save