Skip to content

Commit

Permalink
Add Update of Favorite Status If Exist in Database
Browse files Browse the repository at this point in the history
  • Loading branch information
helloItsHEssam committed Nov 5, 2023
1 parent 852364d commit 1692986
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 5 deletions.
1 change: 1 addition & 0 deletions Data/Sources/Data/Local/Local.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ public protocol Local {
func fetchFavoritePersonAccounts() async throws -> [PersonBankAccount]
func savePersonAccountToFavorites(_ personBankAccount: PersonBankAccount) async throws -> PersonBankAccount
func removePersonAccountFromFavorites(_ personBankAccount: PersonBankAccount) async throws -> PersonBankAccount
func updatefavoriteStatusBasedOnFavorites(_ personBankAccount: PersonBankAccount) async -> PersonBankAccount
}
46 changes: 46 additions & 0 deletions Data/Sources/Data/Local/LocalImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,50 @@ public class LocalImpl: Local {
}
}
}

public func updatefavoriteStatusBasedOnFavorites(_ personBankAccount: PersonBankAccount) async -> PersonBankAccount {
return await withCheckedContinuation { [weak self] continuation in
guard let self else {
continuation.resume(returning: personBankAccount)
return
}

self.database.backgroundContext.performAndWait { [weak self] in
guard let self else {
continuation.resume(returning: personBankAccount)
return
}

do {
let fetchRequest:
NSFetchRequest<PersonBankAccountEntity> = PersonBankAccountEntity.fetchRequest()
let sort = PersonBankAccountEntity.sortDescriptor
fetchRequest.sortDescriptors = [sort]
fetchRequest.fetchLimit = 1

let namePredicate = NSPredicate(format: "person.name == %@",
personBankAccount.person?.name ?? "")
let cardNumberPredicate = NSPredicate(format: "card.cardNumber == %@",
personBankAccount.card?.cardNumber ?? "")
let predicate = NSCompoundPredicate(type: .and,
subpredicates: [namePredicate, cardNumberPredicate])
fetchRequest.predicate = predicate

try Task.checkCancellation()
let accounts = try self.database.backgroundContext.fetch(fetchRequest)
guard let entity = accounts.first else {
continuation.resume(returning: personBankAccount)
return
}

var newPersonBankAccount = personBankAccount
newPersonBankAccount.update(favoriteStatus: entity.isFavorite)
continuation.resume(returning: newPersonBankAccount)

} catch {
continuation.resume(returning: personBankAccount)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public class PersonBankAccountRepositoryImpl: PersonBankAccountRepository {
try await local.removePersonAccountFromFavorites(personBankAccount)
}

public func updatefavoriteStatusForPersonAccount(_ personBankAccount: Domain.PersonBankAccount) async -> Domain.PersonBankAccount {
fatalError()
public func updatefavoriteStatusBasedOnFavorites(_ personBankAccount: PersonBankAccount) async -> PersonBankAccount {
await local.updatefavoriteStatusBasedOnFavorites(personBankAccount)
}
}
41 changes: 40 additions & 1 deletion Data/Tests/DataTests/LocalTests/LocalTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ final class LocalTests: XCTestCase {

// when
do {
let _ = try await local.savePersonAccountToFavorites(createBankAccount())
let _ = try await local.savePersonAccountToFavorites(createBankAccount())
let accounts = try await local.fetchFavoritePersonAccounts()

XCTAssertEqual(accounts.count, 1)
Expand All @@ -80,4 +80,43 @@ final class LocalTests: XCTestCase {
XCTAssertNil(error)
}
}

func testSuccessUpdateFavoriteStatus() async {

// given
local = LocalImpl(database: MockDatabase())

// when
do {
let _ = try await local.savePersonAccountToFavorites(createBankAccount())
let account = await local.updatefavoriteStatusBasedOnFavorites(createBankAccount())

XCTAssertEqual(account.isFavorite, true)

} catch {
// then
XCTAssertNil(error)
}
}

func testDoesNotUpdateFavoriteStatus() async {

// given
local = LocalImpl(database: MockDatabase())

// when
do {
let _ = try await local.savePersonAccountToFavorites(createBankAccount())
var newAccountDoesNotExsit = createBankAccount()
newAccountDoesNotExsit.person?.name = "new person"
newAccountDoesNotExsit.card?.cardNumber = "453"
let account = await local.updatefavoriteStatusBasedOnFavorites(newAccountDoesNotExsit)

XCTAssertEqual(account.isFavorite, false)

} catch {
// then
XCTAssertNil(error)
}
}
}
15 changes: 15 additions & 0 deletions Data/Tests/DataTests/RepositoriesTests/Mock/MockLocal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ class MockLocal: Local {
newAccount.update(favoriteStatus: false)
return newAccount
}

func updatefavoriteStatusBasedOnFavorites(_ personBankAccount: PersonBankAccount) async -> PersonBankAccount {
var newAccount = personBankAccount
newAccount.update(favoriteStatus: true)
return newAccount
}
}

class MockSucceesRemoveLocal: MockLocal {
Expand All @@ -64,3 +70,12 @@ class MockFailFetchFavoriteAccountLocal: MockLocal {
throw LocalError.cannotFetchFavorites
}
}

class MockDoesNotExistInFavoriteLocal: MockLocal {

override func updatefavoriteStatusBasedOnFavorites(_ personBankAccount: PersonBankAccount) async -> PersonBankAccount {
var newAccount = personBankAccount
newAccount.update(favoriteStatus: false)
return newAccount
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,44 @@ final class PersonBankAccountRepositoryTests: XCTestCase {
XCTAssertEqual(error as? LocalError, .cannotFetchFavorites)
}
}

func testSuccessUpdateFavoriteStatus() async {

// given
let local = MockLocal()
repository = PersonBankAccountRepositoryImpl(api: MockApi(),
local: local)

// when
do {
let _ = try await repository.savePersonAccountToFavorites(local.createAccount())
let account = await repository.updatefavoriteStatusBasedOnFavorites(local.createAccount())

XCTAssertEqual(account.isFavorite, true)

} catch {
// then
XCTAssertNil(error)
}
}

func testDoesNotUpdateFavoriteStatus() async {

// given
let local = MockDoesNotExistInFavoriteLocal()
repository = PersonBankAccountRepositoryImpl(api: MockApi(),
local: local)

// when
do {
let _ = try await repository.savePersonAccountToFavorites(local.createAccount())
let account = await repository.updatefavoriteStatusBasedOnFavorites(local.createAccount())

XCTAssertEqual(account.isFavorite, false)

} catch {
// then
XCTAssertNil(error)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ public protocol PersonBankAccountRepository {
func fetchFavoritePersonAccounts() async throws -> [PersonBankAccount]
func savePersonAccountToFavorites(_ personBankAccount: PersonBankAccount) async throws -> PersonBankAccount
func removePersonAccountFromFavorites(_ personBankAccount: PersonBankAccount) async throws -> PersonBankAccount
func updatefavoriteStatusForPersonAccount(_ personBankAccount: PersonBankAccount) async -> PersonBankAccount
func updatefavoriteStatusBasedOnFavorites(_ personBankAccount: PersonBankAccount) async -> PersonBankAccount
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public class PersonBankAccountUseCaseImpl: PersonBankAccountUseCase {
func createUpdateFavoriteStatusTask(atIndex index: Int) {
taskGroup.addTask {
var updatedAccount = await self.repository
.updatefavoriteStatusForPersonAccount(accounts[index])
.updatefavoriteStatusBasedOnFavorites(accounts[index])
updatedAccount.update(indexAtList: index)
return updatedAccount
}
Expand Down

0 comments on commit 1692986

Please sign in to comment.