Prepare CoinTickerFetcher for tests #5012

pull/5013/head
Krypto Pank 2 years ago
parent 2d2072c39f
commit 5c56ade5f0
  1. 4
      AlphaWallet.xcodeproj/project.pbxproj
  2. 18
      AlphaWallet/AppCoordinator.swift
  3. 15
      AlphaWallet/Core/CoinTicker/CoinGecko/CoinGeckoTickersFetcher.swift
  4. 12
      AlphaWallet/Core/CoinTicker/CoinTickersStorage.swift
  5. 47
      AlphaWalletTests/Coordinators/ActiveWalletViewTests.swift
  6. 2
      AlphaWalletTests/Coordinators/TokensCoordinatorTests.swift
  7. 30
      AlphaWalletTests/Factories/FakeCoinTickersFetcher.swift
  8. 3
      AlphaWalletTests/Factories/FakeMultiWalletBalanceService.swift
  9. 10
      AlphaWalletTests/Settings/ConfigTests.swift
  10. 4
      modules/AlphaWalletCore/AlphaWalletCore/StorageType.swift

@ -989,6 +989,7 @@
8775728C282E8FDC00EAD907 /* SvgImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8775728B282E8FDC00EAD907 /* SvgImageView.swift */; };
8775728E282E902D00EAD907 /* ImageOrWebImageUrl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8775728D282E902D00EAD907 /* ImageOrWebImageUrl.swift */; };
87757290282EA12100EAD907 /* ViewRounding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8775728F282EA12100EAD907 /* ViewRounding.swift */; };
877581B32886E81300701808 /* FakeCoinTickersFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 877581B22886E81300701808 /* FakeCoinTickersFetcher.swift */; };
877D00AF25ADF60A008E22CC /* TransactionConfiguratorTransactionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 877D00AE25ADF60A008E22CC /* TransactionConfiguratorTransactionsTests.swift */; };
8780FDAD27BF883F00BBE9DD /* ActivityOrTransactionInstance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8780FDAC27BF883F00BBE9DD /* ActivityOrTransactionInstance.swift */; };
8780FDAF27BF887700BBE9DD /* ActivitiesFilterStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8780FDAE27BF887700BBE9DD /* ActivitiesFilterStrategy.swift */; };
@ -2265,6 +2266,7 @@
8775728B282E8FDC00EAD907 /* SvgImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SvgImageView.swift; sourceTree = "<group>"; };
8775728D282E902D00EAD907 /* ImageOrWebImageUrl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageOrWebImageUrl.swift; sourceTree = "<group>"; };
8775728F282EA12100EAD907 /* ViewRounding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewRounding.swift; sourceTree = "<group>"; };
877581B22886E81300701808 /* FakeCoinTickersFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeCoinTickersFetcher.swift; sourceTree = "<group>"; };
877D00AE25ADF60A008E22CC /* TransactionConfiguratorTransactionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionConfiguratorTransactionsTests.swift; sourceTree = "<group>"; };
8780FDAC27BF883F00BBE9DD /* ActivityOrTransactionInstance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityOrTransactionInstance.swift; sourceTree = "<group>"; };
8780FDAE27BF887700BBE9DD /* ActivitiesFilterStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivitiesFilterStrategy.swift; sourceTree = "<group>"; };
@ -3910,6 +3912,7 @@
8765D6F0282BDDC400529F45 /* FakeTokenSwapper.swift */,
8765D6F2282BDF8400529F45 /* FakeTokenGroupIdentifier.swift */,
8792707B284F40D1006F5AE5 /* FakeEnsRecordsStorage.swift */,
877581B22886E81300701808 /* FakeCoinTickersFetcher.swift */,
);
path = Factories;
sourceTree = "<group>";
@ -7699,6 +7702,7 @@
290B2B6A1F92C0440053C83E /* ConfigTests.swift in Sources */,
8739912D2861ED9B00465D3C /* LogLargeNftJsonFilesTests.swift in Sources */,
29BDF1941FEE43AA0023A45F /* TransactionConfiguratorTests.swift in Sources */,
877581B32886E81300701808 /* FakeCoinTickersFetcher.swift in Sources */,
29FF13081F75F0AE00AFD326 /* AppCoordinatorTests.swift in Sources */,
2923D9B71FDA5E51000CF3F8 /* PasswordGeneratorTests.swift in Sources */,
29F1C865200384FE003780D8 /* Wallet.swift in Sources */,

@ -3,6 +3,7 @@
import Combine
import UIKit
import PromiseKit
import AlphaWalletCore
class AppCoordinator: NSObject, Coordinator {
private let config = Config()
@ -39,14 +40,27 @@ class AppCoordinator: NSObject, Coordinator {
private let localStore: LocalStore = RealmLocalStore()
private lazy var coinTickersFetcher: CoinTickersFetcherType = {
let networkProvider: CoinGeckoNetworkProviderType
let persistentStorage: StorageType
if isRunningTests() {
networkProvider = FakeCoinGeckoNetworkProvider()
persistentStorage = try! FileStorage.forTestSuite(folder: "testSuiteForTickersStorage", fileExtension: "json")
} else {
networkProvider = CoinGeckoNetworkProvider(provider: AlphaWalletProviderFactory.makeProvider())
persistentStorage = FileStorage(fileExtension: "json")
}
let storage = CoinTickersFileStorage(config: config)
return CoinGeckoTickersFetcher(networkProvider: networkProvider, config: config, storage: storage)
let storage: CoinTickersStorage & ChartHistoryStorage & TickerIdsStorage = CoinTickersFileStorage(config: config, storage: persistentStorage)
let coinGeckoTickerIdsFetcher = CoinGeckoTickerIdsFetcher(networkProvider: networkProvider, storage: storage, config: config)
let fileTokenEntriesProvider = FileTokenEntriesProvider(fileName: "tokens_2")
let tickerIdsFetcher: TickerIdsFetcher = TickerIdsFetcherImpl(providers: [
InMemoryTickerIdsFetcher(storage: storage),
coinGeckoTickerIdsFetcher,
AlphaWalletRemoteTickerIdsFetcher(provider: fileTokenEntriesProvider, tickerIdsFetcher: coinGeckoTickerIdsFetcher)
])
return CoinGeckoTickersFetcher(networkProvider: networkProvider, storage: storage, tickerIdsFetcher: tickerIdsFetcher)
}()
private lazy var walletBalanceService: WalletBalanceService = {
return MultiWalletBalanceService(store: localStore, keystore: keystore, config: config, assetDefinitionStore: assetDefinitionStore, analyticsCoordinator: analyticsService, coinTickersFetcher: coinTickersFetcher, walletAddressesStore: walletAddressesStore)

@ -11,10 +11,9 @@ import Foundation
final class CoinGeckoTickersFetcher: CoinTickersFetcherType {
private let pricesCacheLifetime: TimeInterval = 60 * 60
private let dayChartHistoryCacheLifetime: TimeInterval = 60 * 60
private let config: Config
private let storage: CoinTickersStorage & ChartHistoryStorage & TickerIdsStorage
private let networkProvider: CoinGeckoNetworkProviderType
private let tickerIdsFetcher: TickerIdsFetcherImpl
private let tickerIdsFetcher: TickerIdsFetcher
/// Cached fetch ticker prices operations
private var promises: AtomicDictionary<TokenMappedToTicker, AnyCancellable> = .init()
/// Ticker last update dates
@ -30,17 +29,9 @@ final class CoinGeckoTickersFetcher: CoinTickersFetcherType {
storage.updateTickerId
}
init(networkProvider: CoinGeckoNetworkProviderType, config: Config, storage: CoinTickersStorage & ChartHistoryStorage & TickerIdsStorage) {
init(networkProvider: CoinGeckoNetworkProviderType, storage: CoinTickersStorage & ChartHistoryStorage & TickerIdsStorage, tickerIdsFetcher: TickerIdsFetcher) {
self.networkProvider = networkProvider
let coinGeckoTickerIdsFetcher = CoinGeckoTickerIdsFetcher(networkProvider: networkProvider, storage: storage, config: config)
let fileTokenEntriesProvider = FileTokenEntriesProvider(fileName: "tokens_2")
self.tickerIdsFetcher = TickerIdsFetcherImpl(providers: [
InMemoryTickerIdsFetcher(storage: storage),
coinGeckoTickerIdsFetcher,
AlphaWalletRemoteTickerIdsFetcher(provider: fileTokenEntriesProvider, tickerIdsFetcher: coinGeckoTickerIdsFetcher)
])
self.config = config
self.tickerIdsFetcher = tickerIdsFetcher
self.storage = storage
}

@ -40,15 +40,13 @@ class CoinTickersFileStorage: NSObject {
private let tickersStore: Storage<[AssignedCoinTickerId: CoinTicker]>
private let allTickersIdsStore: Storage<[TickerId]>
private let knownTickersIdsStore: Storage<[AddressAndRPCServer: TickerIdString]>
private var config: Config
private let updateTickerIdSubject: PassthroughSubject<(tickerId: TickerIdString, key: AddressAndRPCServer), Never> = .init()
init(config: Config) {
self.config = config
historyStore = .init(fileName: "history", storage: FileStorage(fileExtension: "json"), defaultValue: [:])
allTickersIdsStore = .init(fileName: "tickersIds", storage: FileStorage(fileExtension: "json"), defaultValue: [])
tickersStore = .init(fileName: "tickers", storage: FileStorage(fileExtension: "json"), defaultValue: [:])
knownTickersIdsStore = .init(fileName: "knownTickersIds", storage: FileStorage(fileExtension: "json"), defaultValue: [:])
init(config: Config, storage: StorageType) {
historyStore = .init(fileName: "history", storage: storage, defaultValue: [:])
allTickersIdsStore = .init(fileName: "tickersIds", storage: storage, defaultValue: [])
tickersStore = .init(fileName: "tickers", storage: storage, defaultValue: [:])
knownTickersIdsStore = .init(fileName: "knownTickersIds", storage: storage, defaultValue: [:])
super.init()
CoinTickersFileStorage.migrateTickerIdsFrom_v1To_v2(config: config, storage: self)
}

@ -43,7 +43,7 @@ class ActiveWalletViewTests: XCTestCase {
universalLinkCoordinator: FakeUniversalLinkCoordinator.make(),
accountsCoordinator: ac,
walletBalanceService: FakeMultiWalletBalanceService(),
coinTickersFetcher: FakeCoinTickersFetcher(),
coinTickersFetcher: CoinGeckoTickersFetcher.make(),
tokenActionsService: FakeSwapTokenService(),
walletConnectCoordinator: .fake(),
notificationService: FakeNotificationService(),
@ -103,7 +103,7 @@ class ActiveWalletViewTests: XCTestCase {
universalLinkCoordinator: FakeUniversalLinkCoordinator.make(),
accountsCoordinator: ac,
walletBalanceService: FakeMultiWalletBalanceService(),
coinTickersFetcher: FakeCoinTickersFetcher(),
coinTickersFetcher: CoinGeckoTickersFetcher.make(),
tokenActionsService: FakeSwapTokenService(),
walletConnectCoordinator: .fake(),
notificationService: FakeNotificationService(),
@ -130,7 +130,7 @@ class ActiveWalletViewTests: XCTestCase {
universalLinkCoordinator: FakeUniversalLinkCoordinator.make(),
accountsCoordinator: ac,
walletBalanceService: FakeMultiWalletBalanceService(),
coinTickersFetcher: FakeCoinTickersFetcher(),
coinTickersFetcher: CoinGeckoTickersFetcher.make(),
tokenActionsService: FakeSwapTokenService(),
walletConnectCoordinator: .fake(),
notificationService: FakeNotificationService(),
@ -165,7 +165,7 @@ class ActiveWalletViewTests: XCTestCase {
universalLinkCoordinator: FakeUniversalLinkCoordinator.make(),
accountsCoordinator: ac,
walletBalanceService: FakeMultiWalletBalanceService(),
coinTickersFetcher: FakeCoinTickersFetcher(),
coinTickersFetcher: CoinGeckoTickersFetcher.make(),
tokenActionsService: FakeSwapTokenService(),
walletConnectCoordinator: .fake(),
notificationService: FakeNotificationService(),
@ -201,7 +201,7 @@ class ActiveWalletViewTests: XCTestCase {
universalLinkCoordinator: FakeUniversalLinkCoordinator.make(),
accountsCoordinator: ac,
walletBalanceService: FakeMultiWalletBalanceService(),
coinTickersFetcher: FakeCoinTickersFetcher(),
coinTickersFetcher: CoinGeckoTickersFetcher.make(),
tokenActionsService: FakeSwapTokenService(),
walletConnectCoordinator: .fake(),
notificationService: FakeNotificationService(),
@ -237,7 +237,7 @@ class ActiveWalletViewTests: XCTestCase {
universalLinkCoordinator: FakeUniversalLinkCoordinator.make(),
accountsCoordinator: ac,
walletBalanceService: FakeMultiWalletBalanceService(),
coinTickersFetcher: FakeCoinTickersFetcher(),
coinTickersFetcher: CoinGeckoTickersFetcher.make(),
tokenActionsService: FakeSwapTokenService(),
walletConnectCoordinator: .fake(),
notificationService: FakeNotificationService(),
@ -292,7 +292,7 @@ class ActiveWalletViewTests: XCTestCase {
universalLinkCoordinator: FakeUniversalLinkCoordinator.make(),
accountsCoordinator: ac,
walletBalanceService: FakeMultiWalletBalanceService(),
coinTickersFetcher: FakeCoinTickersFetcher(),
coinTickersFetcher: CoinGeckoTickersFetcher.make(),
tokenActionsService: FakeSwapTokenService(),
walletConnectCoordinator: .fake(),
notificationService: FakeNotificationService(),
@ -313,36 +313,3 @@ class ActiveWalletViewTests: XCTestCase {
}
}
}
import Combine
final class FakeCoinTickersFetcher: CoinTickersFetcherType {
var tickersDidUpdate: AnyPublisher<Void, Never> {
return Empty<Void, Never>(completeImmediately: true).eraseToAnyPublisher()
}
var updateTickerId: AnyPublisher<(tickerId: TickerIdString, key: AddressAndRPCServer), Never> {
return Empty<(tickerId: TickerIdString, key: AddressAndRPCServer), Never>(completeImmediately: true).eraseToAnyPublisher()
}
func ticker(for addressAndPRCServer: AddressAndRPCServer) -> CoinTicker? {
return nil
}
func fetchTickers(for tokens: [TokenMappedToTicker], force: Bool) {
//no-op
}
func resolveTikerIds(for tokens: [TokenMappedToTicker]) {
//no-op
}
func fetchChartHistories(for token: TokenMappedToTicker, force: Bool, periods: [ChartHistoryPeriod]) -> AnyPublisher<[ChartHistory], Never> {
return Empty<[ChartHistory], Never>(completeImmediately: true).eraseToAnyPublisher()
}
func cancel() {
//no-op
}
}

@ -28,7 +28,7 @@ class TokensCoordinatorTests: XCTestCase {
openSea: OpenSea(analyticsCoordinator: FakeAnalyticsService(), queue: .global()),
tokenActionsService: tokenActionsService,
walletConnectCoordinator: .fake(),
coinTickersFetcher: FakeCoinTickersFetcher(),
coinTickersFetcher: CoinGeckoTickersFetcher.make(),
activitiesService: FakeActivitiesService(),
walletBalanceService: FakeMultiWalletBalanceService(),
tokenCollection: MultipleChainsTokenCollection.fake(),

@ -0,0 +1,30 @@
//
// FakeCoinTickersFetcher.swift
// AlphaWalletTests
//
// Created by Vladyslav Shepitko on 19.07.2022.
//
import XCTest
import Combine
@testable import AlphaWallet
import AlphaWalletCore
extension CoinGeckoTickersFetcher {
static func make(config: Config = .make()) -> CoinTickersFetcherType {
let networkProvider: CoinGeckoNetworkProviderType = FakeCoinGeckoNetworkProvider()
let persistentStorage: StorageType = try! FileStorage.forTestSuite(folder: "testSuiteForTickersStorage", fileExtension: "json")
let storage: CoinTickersStorage & ChartHistoryStorage & TickerIdsStorage = CoinTickersFileStorage(config: config, storage: persistentStorage)
let coinGeckoTickerIdsFetcher = CoinGeckoTickerIdsFetcher(networkProvider: networkProvider, storage: storage, config: config)
let fileTokenEntriesProvider = FileTokenEntriesProvider(fileName: "tokens_2")
let tickerIdsFetcher: TickerIdsFetcher = TickerIdsFetcherImpl(providers: [
InMemoryTickerIdsFetcher(storage: storage),
coinGeckoTickerIdsFetcher,
AlphaWalletRemoteTickerIdsFetcher(provider: fileTokenEntriesProvider, tickerIdsFetcher: coinGeckoTickerIdsFetcher)
])
return CoinGeckoTickersFetcher(networkProvider: networkProvider, storage: storage, tickerIdsFetcher: tickerIdsFetcher)
}
}

@ -16,7 +16,6 @@ class FakeMultiWalletBalanceService: MultiWalletBalanceService {
self.servers = servers
self.wallet = wallet
let tickersFetcher = FakeCoinTickersFetcher()
var walletAddressesStore = EtherKeystore.migratedWalletAddressesStore(userDefaults: .test)
switch wallet.type {
case .real:
@ -26,7 +25,7 @@ class FakeMultiWalletBalanceService: MultiWalletBalanceService {
}
let keystore = FakeKeystore(wallets: [wallet], recentlyUsedWallet: wallet)
super.init(store: FakeRealmLocalStore(), keystore: keystore, config: .make(), assetDefinitionStore: .init(), analyticsCoordinator: FakeAnalyticsService(), coinTickersFetcher: tickersFetcher, walletAddressesStore: walletAddressesStore)
super.init(store: FakeRealmLocalStore(), keystore: keystore, config: .make(), assetDefinitionStore: .init(), analyticsCoordinator: FakeAnalyticsService(), coinTickersFetcher: CoinGeckoTickersFetcher.make(), walletAddressesStore: walletAddressesStore)
}
override func createWalletBalanceFetcher(wallet: Wallet) -> WalletBalanceFetcherType {

@ -21,11 +21,10 @@ extension MultipleChainsTokenCollection {
static func fake() -> MultipleChainsTokenCollection {
let tokensDataStore = FakeTokensDataStore()
let config: Config = .make()
let coinTickersFetcher = FakeCoinTickersFetcher()
let actionsService = TokenActionsService()
let tokenGroupIdentifier: TokenGroupIdentifierProtocol = FakeTokenGroupIdentifier()
let tokensFilter = TokensFilter(assetDefinitionStore: .init(), tokenActionsService: actionsService, coinTickersFetcher: coinTickersFetcher, tokenGroupIdentifier: tokenGroupIdentifier)
return MultipleChainsTokenCollection(tokensFilter: tokensFilter, tokensDataStore: tokensDataStore, config: config, coinTickersFetcher: coinTickersFetcher)
let tokensFilter = TokensFilter(assetDefinitionStore: .init(), tokenActionsService: actionsService, coinTickersFetcher: CoinGeckoTickersFetcher.make(), tokenGroupIdentifier: tokenGroupIdentifier)
return MultipleChainsTokenCollection(tokensFilter: tokensFilter, tokensDataStore: tokensDataStore, config: config, coinTickersFetcher: CoinGeckoTickersFetcher.make())
}
}
@ -45,7 +44,6 @@ class ConfigTests: XCTestCase {
let config: Config = .make()
Config.setLocale(AppLocale.english)
let coinTickersFetcher = FakeCoinTickersFetcher()
let tokenActionsService = FakeSwapTokenService()
let coordinator_1 = TokensCoordinator(
@ -60,7 +58,7 @@ class ConfigTests: XCTestCase {
openSea: OpenSea(analyticsCoordinator: FakeAnalyticsService(), queue: .global()),
tokenActionsService: tokenActionsService,
walletConnectCoordinator: .fake(),
coinTickersFetcher: coinTickersFetcher,
coinTickersFetcher: CoinGeckoTickersFetcher.make(),
activitiesService: FakeActivitiesService(),
walletBalanceService: FakeMultiWalletBalanceService(),
tokenCollection: MultipleChainsTokenCollection.fake(),
@ -87,7 +85,7 @@ class ConfigTests: XCTestCase {
openSea: OpenSea(analyticsCoordinator: FakeAnalyticsService(), queue: .global()),
tokenActionsService: tokenActionsService,
walletConnectCoordinator: .fake(),
coinTickersFetcher: coinTickersFetcher,
coinTickersFetcher: CoinGeckoTickersFetcher.make(),
activitiesService: FakeActivitiesService(),
walletBalanceService: FakeMultiWalletBalanceService(),
tokenCollection: MultipleChainsTokenCollection.fake(),

@ -142,11 +142,11 @@ public extension URL {
}
public extension FileStorage {
static func forTestSuite(folder: String = "testSuiteForAddressStorage") throws -> FileStorage {
static func forTestSuite(folder: String = "testSuiteForAddressStorage", fileExtension: String = "json") throws -> FileStorage {
try removeAddressFolderForTests(name: folder)
let url = try addressStorageUrlInCacheFolder(folder)
return FileStorage(fileExtension: "json", directoryUrl: url)
return FileStorage(fileExtension: fileExtension, directoryUrl: url)
}
private static func addressStorageUrlInCacheFolder(_ folder: String) throws -> URL {

Loading…
Cancel
Save