diff --git a/Tests/CategoryFetchingTests.swift b/Tests/CategoryFetchingTests.swift index 84c3e53e..fd68a373 100644 --- a/Tests/CategoryFetchingTests.swift +++ b/Tests/CategoryFetchingTests.swift @@ -20,32 +20,123 @@ import SwiftUI final class CategoryFetchingTests: XCTestCase { - func testSingleZIMIsFilteredOutByLanguage() throws { + override func setUpWithError() throws { + try resetDB() + } + + func testFilteredOutByLanguage() throws { // insert a zimFile let context = Database.viewContext let zimFile = ZimFile(context: context) - let metadata = ZimFileMetaData.mock(languageCodes: "en", category: Category.other.rawValue) + let metadata = ZimFileMetaData.mock(languageCodes: "eng", + category: Category.other.rawValue) LibraryOperations.configureZimFile(zimFile, metadata: metadata) try? context.save() let request = NSFetchRequest(entityName: ZimFile.entity().name!) - request.predicate = ZimFilesCategory.buildPredicate(category: .other, searchText: "", languageCodes: Set(["xx"])) + request.predicate = ZimFilesCategory.buildPredicate( + category: .other, + searchText: "", + languageCodes: Set(["x"]) + ) let results = try! context.fetch(request) XCTAssertTrue(results.isEmpty) } - func testSingleZIMCanBeFoundByLanguage() throws { + func testCanBeFoundByLanguage() throws { // insert a zimFile let context = Database.viewContext let zimFile = ZimFile(context: context) - let metadata = ZimFileMetaData.mock(languageCodes: "en", category: Category.other.rawValue) + let metadata = ZimFileMetaData.mock(languageCodes: "eng", + category: Category.other.rawValue) LibraryOperations.configureZimFile(zimFile, metadata: metadata) try? context.save() let request = NSFetchRequest(entityName: ZimFile.entity().name!) - request.predicate = ZimFilesCategory.buildPredicate(category: .other, searchText: "", languageCodes: Set(["en"])) + request.predicate = ZimFilesCategory.buildPredicate( + category: .other, + searchText: "", + languageCodes: Set(["eng"]) + ) let results = try! context.fetch(request) XCTAssertEqual(results.count, 1) } + func testCanBeFoundByMultipleUserLanguages() throws { + // insert a zimFile + let context = Database.viewContext + let zimFile = ZimFile(context: context) + let metadata = ZimFileMetaData.mock(languageCodes: "fra", + category: Category.other.rawValue) + LibraryOperations.configureZimFile(zimFile, metadata: metadata) + try? context.save() + let request = NSFetchRequest(entityName: ZimFile.entity().name!) + request.predicate = ZimFilesCategory.buildPredicate( + category: .other, + searchText: "", + languageCodes: Set(["eng","deu","fra","ita","por"]) + ) + let results = try! context.fetch(request) + XCTAssertEqual(results.count, 1) + } + + func testCanBeFoundHavingMultiLanguagesWithASingleUserLanguage() throws { + // insert a zimFile + let context = Database.viewContext + let zimFile = ZimFile(context: context) + let metadata = ZimFileMetaData.mock(languageCodes: "eng,fra,deu,nld,spa,ita,por,pol,ara,vie,kor", + category: Category.other.rawValue) + LibraryOperations.configureZimFile(zimFile, metadata: metadata) + try? context.save() + let request = NSFetchRequest(entityName: ZimFile.entity().name!) + request.predicate = ZimFilesCategory.buildPredicate( + category: .other, + searchText: "", + languageCodes: Set(["spa"]) + ) + let results = try! context.fetch(request) + XCTAssertEqual(results.count, 1) + } + + func testCanBeFoundHavingMultiLanguageMatches() throws { + // insert a zimFile + let context = Database.viewContext + let zimFile = ZimFile(context: context) + let metadata = ZimFileMetaData.mock(languageCodes: "eng,fra,deu,nld,spa,ita,por,pol,ara,vie,kor", + category: Category.other.rawValue) + LibraryOperations.configureZimFile(zimFile, metadata: metadata) + try? context.save() + let request = NSFetchRequest(entityName: ZimFile.entity().name!) + request.predicate = ZimFilesCategory.buildPredicate( + category: .other, + searchText: "", + languageCodes: Set(["nld","por","fra"]) + ) + let results = try! context.fetch(request) + XCTAssertEqual(results.count, 1) + } + + func testFilteredOutByMultiToMultiLanguageMissMatch() throws { + // insert a zimFile + let context = Database.viewContext + let zimFile = ZimFile(context: context) + let metadata = ZimFileMetaData.mock(languageCodes: "eng,fra,deu,nld,spa,ita", + category: Category.other.rawValue) + LibraryOperations.configureZimFile(zimFile, metadata: metadata) + try? context.save() + let request = NSFetchRequest(entityName: ZimFile.entity().name!) + request.predicate = ZimFilesCategory.buildPredicate( + category: .other, + searchText: "", + languageCodes: Set(["por","pol","ara","vie","kor"]) + ) + let results = try! context.fetch(request) + XCTAssertTrue(results.isEmpty) + } + + private func resetDB() throws { + _ = try Database.viewContext.execute(NSBatchDeleteRequest(fetchRequest: NSFetchRequest(entityName: ZimFile.entity().name!))) + } + + } private extension ZimFileMetaData { diff --git a/Views/Library/ZimFilesCategories.swift b/Views/Library/ZimFilesCategories.swift index fbebe76e..b8122ec8 100644 --- a/Views/Library/ZimFilesCategories.swift +++ b/Views/Library/ZimFilesCategories.swift @@ -75,9 +75,13 @@ struct ZimFilesCategory: View { searchText: String, languageCodes: Set = Defaults[.libraryLanguageCodes] ) -> NSPredicate { + let langPredicates = languageCodes.map { langCode -> NSPredicate in + let regex = String(format: "(.*,)?%@(,.*)?", langCode) + return NSPredicate(format: "languageCode MATCHES %@", regex) + } var predicates = [ NSPredicate(format: "category == %@", category.rawValue), - NSPredicate(format: "languageCode IN %@", languageCodes), + NSCompoundPredicate(orPredicateWithSubpredicates: langPredicates), NSPredicate(format: "requiresServiceWorkers == false") ] if !searchText.isEmpty {