Skip to content

Commit b5f0a1f

Browse files
committed
Documenting CASCADE delete for orphaned variations
Tests that variations are automatically deleted when their parent product is deleted due to foreign key constraints with CASCADE delete. This documents that the noParentProductForVariation error thrown in searchVariationByGlobalUniqueID is defensive code that won't be triggered in normal operation, since the database prevents orphaned variations from existing.
1 parent f01164d commit b5f0a1f

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

Modules/Tests/YosemiteTests/PointOfSale/PointOfSaleLocalBarcodeScanServiceTests.swift

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,67 @@ struct PointOfSaleLocalBarcodeScanServiceTests {
219219
}
220220
}
221221

222+
@Test("Foreign key constraint prevents orphaned variations")
223+
func test_variations_cannot_be_orphaned() async throws {
224+
// Given
225+
let barcode = "ORPHAN-VAR-123"
226+
227+
// Insert a parent product
228+
let parentProduct = PersistedProduct(
229+
id: 888,
230+
siteID: siteID,
231+
name: "Parent Product",
232+
productTypeKey: "variable",
233+
fullDescription: nil,
234+
shortDescription: nil,
235+
sku: nil,
236+
globalUniqueID: nil,
237+
price: "0.00",
238+
downloadable: false,
239+
parentID: 0,
240+
manageStock: false,
241+
stockQuantity: nil,
242+
stockStatusKey: "instock"
243+
)
244+
try await insertProduct(parentProduct)
245+
246+
// Insert the variation
247+
let variation = PersistedProductVariation(
248+
id: 999,
249+
siteID: siteID,
250+
productID: 888,
251+
sku: nil,
252+
globalUniqueID: barcode,
253+
price: "20.00",
254+
downloadable: false,
255+
fullDescription: nil,
256+
manageStock: false,
257+
stockQuantity: nil,
258+
stockStatusKey: "instock"
259+
)
260+
try await insertVariation(variation)
261+
262+
// Verify the variation exists
263+
let variationExists = try await grdbManager.databaseConnection.read { db in
264+
try PersistedProductVariation.fetchOne(db, key: ["siteID": siteID, "id": 999]) != nil
265+
}
266+
#expect(variationExists, "Variation should exist after insertion")
267+
268+
// When - Delete the parent product (with foreign keys enabled)
269+
try await grdbManager.databaseConnection.write { db in
270+
try db.execute(sql: "DELETE FROM product WHERE id = ? AND siteID = ?", arguments: [888, siteID])
271+
}
272+
273+
// Then - Variation should be automatically deleted by CASCADE
274+
let variationStillExists = try await grdbManager.databaseConnection.read { db in
275+
try PersistedProductVariation.fetchOne(db, key: ["siteID": siteID, "id": 999]) != nil
276+
}
277+
#expect(!variationStillExists, "Variation should be automatically deleted by CASCADE when parent is deleted")
278+
279+
// This means the noParentProductForVariation error is defensive code that won't be triggered
280+
// in normal operation due to foreign key constraints with CASCADE delete
281+
}
282+
222283
// MARK: - Helper Methods
223284

224285
private func insertProduct(_ product: PersistedProduct) async throws {

0 commit comments

Comments
 (0)