Skip to content
This repository has been archived by the owner on Jun 20, 2023. It is now read-only.

Clear the key packages and app config on ENError = 2 #1359

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions src/xcode/ENA/ENA/Source/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import UIKit
protocol CoronaWarnAppDelegate: AnyObject {
var client: HTTPClient { get }
var downloadedPackagesStore: DownloadedPackagesStore { get }
var store: Store { get }
var store: Store & AppConfigCaching { get }
var appConfigurationProvider: AppConfigurationProviding { get }
var riskProvider: RiskProvider { get }
var exposureManager: ExposureManager { get }
Expand Down Expand Up @@ -99,7 +99,7 @@ extension AppDelegate: ExposureSummaryProvider {
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

let store: Store
let store: Store & AppConfigCaching
let serverEnvironment: ServerEnvironment

private let consumer = RiskConsumer()
Expand All @@ -109,11 +109,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
// use a custom http client that uses/recognized caching mechanisms
let appFetchingClient = CachingHTTPClient(clientConfiguration: client.configuration)

// we currently use the store as common place for temporal persistency
guard let store = store as? AppConfigCaching else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

preconditionFailure("Ensure to provide a proper app config cache")
}

return CachedAppConfiguration(client: appFetchingClient, store: store)
}()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,39 @@ final class DownloadedPackagesSQLLiteStoreTests: XCTestCase {
XCTAssertEqual(store.allDays(country: "DE").count, 7)
XCTAssertEqual(store.allDays(country: "IT").count, 2)
}

func test_ResetRemovesAllKeys() {
let database = FMDatabase.inMemory()
let store = DownloadedPackagesSQLLiteStore(database: database, migrator: SerialMigratorFake(), latestVersion: 0)
store.open()

let keysBin = Data("keys".utf8)
let signature = Data("sig".utf8)

let package = SAPDownloadedPackage(
keysBin: keysBin,
signature: signature
)

// Add days
store.set(country: "DE", day: "2020-06-01", package: package)
store.set(country: "DE", day: "2020-06-02", package: package)
store.set(country: "DE", day: "2020-06-03", package: package)
store.set(country: "IT", day: "2020-06-03", package: package)
store.set(country: "DE", day: "2020-06-04", package: package)
store.set(country: "DE", day: "2020-06-05", package: package)
store.set(country: "DE", day: "2020-06-06", package: package)
store.set(country: "IT", day: "2020-06-06", package: package)
store.set(country: "DE", day: "2020-06-07", package: package)

XCTAssertEqual(store.allDays(country: "DE").count, 7)
XCTAssertEqual(store.allDays(country: "IT").count, 2)

store.reset()
store.open()

XCTAssertEqual(store.allDays(country: "DE").count, 0)
XCTAssertEqual(store.allDays(country: "IT").count, 0)
XCTAssertEqual(database.lastErrorCode(), 0)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ final class ExposureDetectionExecutor: ExposureDetectionDelegate {
private let client: Client

private let downloadedPackagesStore: DownloadedPackagesStore
private let store: Store
private let store: Store & AppConfigCaching
private let exposureDetector: ExposureDetector

init(
client: Client,
downloadedPackagesStore: DownloadedPackagesStore,
store: Store,
store: Store & AppConfigCaching,
exposureDetector: ExposureDetector
) {
self.client = client
Expand Down Expand Up @@ -168,11 +168,26 @@ final class ExposureDetectionExecutor: ExposureDetectionDelegate {
writtenPackages: WrittenPackages,
completion: @escaping (Result<ENExposureDetectionSummary, Error>) -> Void
) -> Progress {

// Clear the key packages and app config on ENError = 2 = .badParameter
// For more details, see: https://jira.itc.sap.com/browse/EXPOSUREAPP-3297
func clearCacheOnError2(error: Error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why call this func ..OnError2 and explain the error code in the comment?
I think we should use a better name here, like
clearCacheOnErrorBadParameter

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:) Renamed!

if let enError = error as? ENError, enError.code == .badParameter {
// Clear the key packages
downloadedPackagesStore.reset()
downloadedPackagesStore.open()

// Clear the app config
store.appConfig = nil
marcussc marked this conversation as resolved.
Show resolved Hide resolved
}
}

func withResultFrom(
summary: ENExposureDetectionSummary?,
error: Error?
) -> Result<ENExposureDetectionSummary, Error> {
if let error = error {
clearCacheOnError2(error: error)
return .failure(error)
}
if let summary = summary {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,53 @@ final class ExposureDetectionExecutorTests: XCTestCase {
)
waitForExpectations(timeout: 2.0)
}

func testDetectSummaryWithConfiguration_Error2BadParameter_ClearsCache() throws {
// Test the case where the exector is asked to run an exposure detection
// We provide an `MockExposureDetector` with an error, and expect this to be returned
let completionExpectation = expectation(description: "Expect that the completion handler is called.")
let expectedError = ENError(.badParameter)

let keysBin = Data("keys".utf8)
let signature = Data("sig".utf8)
let package = SAPDownloadedPackage(
keysBin: keysBin,
signature: signature
)
let packageStore = DownloadedPackagesSQLLiteStore.inMemory()
packageStore.open()
packageStore.set(country: "DE", day: "SomeDay", package: package)

let store = MockTestStore()
store.appConfig = SAP_ApplicationConfiguration()

let sut = ExposureDetectionExecutor.makeWith(
packageStore: packageStore,
store: store,
exposureDetector: MockExposureDetector((nil, expectedError))
)
let exposureDetection = ExposureDetection(
delegate: sut,
appConfigurationProvider: AppConfigurationProviderFake()
)

XCTAssertNotEqual(packageStore.allDays(country: "DE").count, 0)
XCTAssertNotNil(store.appConfig)

sut.exposureDetection(
exposureDetection,
detectSummaryWithConfiguration: ENExposureConfiguration(),
writtenPackages: WrittenPackages(urls: []),
completion: { result in

XCTAssertEqual(packageStore.allDays(country: "DE").count, 0)
XCTAssertNil(store.appConfig)

completionExpectation.fulfill()
}
)
waitForExpectations(timeout: 2.0)
}
}

// MARK: - Private Helper Extensions
Expand All @@ -377,7 +424,7 @@ private extension ExposureDetectionExecutor {
static func makeWith(
client: Client = ClientMock(),
packageStore: DownloadedPackagesStore = DownloadedPackagesSQLLiteStore.inMemory(),
store: Store = MockTestStore(),
store: Store & AppConfigCaching = MockTestStore(),
exposureDetector: MockExposureDetector = MockExposureDetector()
) -> ExposureDetectionExecutor {
ExposureDetectionExecutor(
Expand Down