Skip to content

Commit 527ad51

Browse files
committed
Filter variations without a parent product in the catalog, as the API currently returns all products and variations with public status.
1 parent ed9b1a8 commit 527ad51

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

Modules/Sources/Yosemite/Tools/POS/POSCatalogPersistenceService.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ final class POSCatalogPersistenceService: POSCatalogPersistenceServiceProtocol {
2727
func replaceAllCatalogData(_ catalog: POSCatalog, siteID: Int64) async throws {
2828
DDLogInfo("💾 Persisting catalog with \(catalog.products.count) products and \(catalog.variations.count) variations")
2929

30+
let catalog = filterOrphanedVariations(from: catalog)
31+
3032
try await grdbManager.databaseConnection.write { db in
3133
DDLogInfo("🗑️ Clearing catalog data for site \(siteID)")
3234
try PersistedSite.deleteOne(db, key: siteID)
@@ -154,6 +156,22 @@ final class POSCatalogPersistenceService: POSCatalogPersistenceServiceProtocol {
154156
}
155157
}
156158

159+
private extension POSCatalogPersistenceService {
160+
/// Filters out variations whose parent products are not in the catalog.
161+
/// This can happen when the API returns public variations but their parent products are not public.
162+
func filterOrphanedVariations(from catalog: POSCatalog) -> POSCatalog {
163+
let productIDs = catalog.products.map { $0.productID }
164+
let variations = catalog.variations.filter { variation in
165+
let parentExists = productIDs.contains { $0 == variation.productID }
166+
if !parentExists {
167+
DDLogWarn("Variation \(variation.productVariationID) references missing product \(variation.productID)")
168+
}
169+
return parentExists
170+
}
171+
return POSCatalog(products: catalog.products, variations: variations, syncDate: catalog.syncDate)
172+
}
173+
}
174+
157175
private extension POSCatalog {
158176
var productsToPersist: [PersistedProduct] {
159177
products.map { PersistedProduct(from: $0) }

Modules/Tests/YosemiteTests/Tools/POS/POSCatalogPersistenceServiceTests.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,42 @@ struct POSCatalogPersistenceServiceTests {
564564
#expect(site?.id == sampleSiteID)
565565
}
566566
}
567+
568+
// MARK: - Orphaned Variation Filtering Tests
569+
570+
@Test func replaceAllCatalogData_filters_out_variations_without_parent_products() async throws {
571+
// Given
572+
let product = POSProduct.fake().copy(siteID: sampleSiteID, productID: 10)
573+
let validVariation = POSProductVariation.fake()
574+
.copy(siteID: sampleSiteID, productID: 10, productVariationID: 1, image: ProductImage.fake().copy(imageID: 100))
575+
let orphanedVariation1 = POSProductVariation.fake()
576+
.copy(siteID: sampleSiteID, productID: 20, productVariationID: 2, image: ProductImage.fake().copy(imageID: 200))
577+
let orphanedVariation2 = POSProductVariation.fake()
578+
.copy(siteID: sampleSiteID, productID: 30, productVariationID: 3, image: ProductImage.fake().copy(imageID: 300))
579+
580+
let catalog = POSCatalog(
581+
products: [product],
582+
variations: [validVariation, orphanedVariation1, orphanedVariation2],
583+
syncDate: .now
584+
)
585+
586+
// When
587+
try await sut.replaceAllCatalogData(catalog, siteID: sampleSiteID)
588+
589+
// Then
590+
try await db.read { db in
591+
let variationCount = try PersistedProductVariation.fetchCount(db)
592+
#expect(variationCount == 1)
593+
let variationImageCount = try PersistedProductVariationImage.fetchCount(db)
594+
#expect(variationImageCount == 1)
595+
596+
let variation = try PersistedProductVariation.fetchOne(db)
597+
#expect(variation?.id == 1)
598+
#expect(variation?.productID == 10)
599+
let variationImage = try PersistedProductVariationImage.fetchOne(db)
600+
#expect(variationImage?.imageID == 100)
601+
}
602+
}
567603
}
568604

569605
private extension POSCatalogPersistenceServiceTests {

0 commit comments

Comments
 (0)