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

Commit

Permalink
Merge pull request #2488 from corona-warn-app/fix/6551-error-messages
Browse files Browse the repository at this point in the history
Fix/6551 error messages and other bugs
  • Loading branch information
nickguendling committed Apr 21, 2021
2 parents 7cfbbe9 + ff7acdc commit 687eed4
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,31 @@ extension URLSession.Response {

typealias Completion = (Result<URLSession.Response, Failure>) -> Void
}

extension URLSession.Response.Failure: LocalizedError {
var errorDescription: String? {
switch self {
case let .serverError(code):
return "\(AppStrings.ExposureSubmissionError.other)\(code)\(AppStrings.ExposureSubmissionError.otherend)"
case let .httpError(desc, _):
return "\(AppStrings.ExposureSubmissionError.httpError)\n\(desc)"
case .invalidResponse:
return AppStrings.ExposureSubmissionError.invalidResponse
case .noResponse:
return AppStrings.ExposureSubmissionError.noResponse
case .noNetworkConnection:
return AppStrings.ExposureSubmissionError.noNetworkConnection
case .qrAlreadyUsed:
return AppStrings.ExposureSubmissionError.qrAlreadyUsed
case .qrDoesNotExist:
return AppStrings.ExposureSubmissionError.qrNotExist
case .teleTanAlreadyUsed:
return AppStrings.ExposureSubmissionError.teleTanAlreadyUsed
case .regTokenNotExist:
return AppStrings.ExposureSubmissionError.regTokenNotExist
default:
Log.error("\(self)", log: .api)
return AppStrings.ExposureSubmissionError.defaultError
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class ExposureSubmissionCoordinator: NSObject, RequiresAppDependencies {

func start(with coronaTestType: CoronaTestType? = nil) {
model.coronaTestType = coronaTestType
start(with: getInitialViewController())

start(with: self.getInitialViewController())
}

func start(with testInformationResult: Result<CoronaTestQRCodeInformation, QRCodeError>) {
Expand Down Expand Up @@ -119,7 +120,7 @@ class ExposureSubmissionCoordinator: NSObject, RequiresAppDependencies {
if !coronaTest.positiveTestResultWasShown {
return createTestResultAvailableViewController()
} else {
return createWarnOthersViewController()
return createWarnOthersViewController(supportedCountries: model.exposureSubmissionService.supportedCountries)
}
} else {
return createTestResultViewController()
Expand Down Expand Up @@ -327,12 +328,13 @@ class ExposureSubmissionCoordinator: NSObject, RequiresAppDependencies {
return topBottomContainerViewController
}

private func createWarnOthersViewController() -> UIViewController {
private func createWarnOthersViewController(supportedCountries: [Country]) -> UIViewController {
Analytics.collect(.keySubmissionMetadata(.lastSubmissionFlowScreen(.submissionFlowScreenWarnOthers)))

let vc = ExposureSubmissionWarnOthersViewController(
viewModel: ExposureSubmissionWarnOthersViewModel(
supportedCountries: model.exposureSubmissionService.supportedCountries) { [weak self] in
supportedCountries: supportedCountries
) { [weak self] in
self?.showTestResultAvailableCloseAlert()
},
onPrimaryButtonTap: { [weak self] isLoading in
Expand Down Expand Up @@ -557,6 +559,9 @@ class ExposureSubmissionCoordinator: NSObject, RequiresAppDependencies {
showNextScreen()
return
}

/// Reset checkins when entering the screen in case the user skips, cancels or stays on the screen during background submission
model.exposureSubmissionService.checkins = []

let footerViewModel = FooterViewModel(
primaryButtonName: AppStrings.ExposureSubmissionCheckins.continueButton,
Expand All @@ -572,13 +577,11 @@ class ExposureSubmissionCoordinator: NSObject, RequiresAppDependencies {
showNextScreen()
},
onSkip: { [weak self] in
self?.model.exposureSubmissionService.checkins = []
self?.showSkipCheckinsAlert(dontShareHandler: {
showNextScreen()
})
},
onDismiss: { [weak self] in
self?.model.exposureSubmissionService.checkins = []
if self?.model.coronaTest?.positiveTestResultWasShown == true {
self?.showSkipCheckinsAlert(dontShareHandler: {
Analytics.collect(.keySubmissionMetadata(.submittedAfterCancel(true)))
Expand All @@ -603,52 +606,8 @@ class ExposureSubmissionCoordinator: NSObject, RequiresAppDependencies {
// MARK: Late consent

private func showWarnOthersScreen(supportedCountries: [Country]) {
Analytics.collect(.keySubmissionMetadata(.lastSubmissionFlowScreen(.submissionFlowScreenWarnOthers)))
let viewModel = ExposureSubmissionWarnOthersViewModel(supportedCountries: supportedCountries) { [weak self] in
self?.showTestResultAvailableCloseAlert()
}
let vc = ExposureSubmissionWarnOthersViewController(
viewModel: viewModel,
onPrimaryButtonTap: { [weak self] isLoading in
self?.model.setSubmissionConsentGiven(true)
self?.model.exposureSubmissionService.getTemporaryExposureKeys { error in
isLoading(false)

guard let error = error else {
self?.showCheckinsScreen()
return
}

self?.model.setSubmissionConsentGiven(false)

// User selected "Don't Share" / "Nicht teilen"
if error == .notAuthorized {
Log.info("OS submission authorization was declined.")
} else {
Log.error("\(#function) error", log: .ui, error: error)
self?.showErrorAlert(for: error)
}
}
},
dismiss: { [weak self] in self?.dismiss() }
)

let footerViewController = FooterViewController(
FooterViewModel(
primaryButtonName: AppStrings.ExposureSubmissionQRInfo.primaryButtonTitle,
primaryIdentifier: AccessibilityIdentifiers.ExposureSubmission.primaryButton,
secondaryIdentifier: AccessibilityIdentifiers.ExposureSubmission.secondaryButton,
isSecondaryButtonEnabled: false,
isSecondaryButtonHidden: true
)
)

let topBottomContainerViewController = TopBottomContainerViewController(
topController: vc,
bottomController: footerViewController
)

push(topBottomContainerViewController)
let vc = createWarnOthersViewController(supportedCountries: supportedCountries)
push(vc)
}

private func showThankYouScreen() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,36 @@ class HomeTestResultCellModel {
) {
self.coronaTestType = coronaTestType
self.coronaTestService = coronaTestService
self.onUpdate = onUpdate

setup()
}

// MARK: - Internal

@OpenCombine.Published var title: String! = ""
@OpenCombine.Published var subtitle: String?
@OpenCombine.Published var description: String! = ""
@OpenCombine.Published var footnote: String?
@OpenCombine.Published var buttonTitle: String! = ""
@OpenCombine.Published var image: UIImage?
@OpenCombine.Published var isDisclosureIndicatorHidden: Bool = false
@OpenCombine.Published var isNegativeDiagnosisHidden: Bool = true
@OpenCombine.Published var isActivityIndicatorHidden: Bool = false
@OpenCombine.Published var isUserInteractionEnabled: Bool = false
@OpenCombine.Published var isCellTappable: Bool = true
@OpenCombine.Published var accessibilityIdentifier: String! = AccessibilityIdentifiers.Home.submitCardButton

// MARK: - Private

private let coronaTestType: CoronaTestType
private let coronaTestService: CoronaTestService
private let onUpdate: () -> Void

private var subscriptions = Set<AnyCancellable>()

// swiftlint:disable:next cyclomatic_complexity
private func setup() {
switch coronaTestType {
case .pcr:
title = AppStrings.Home.TestResult.pcrTitle
Expand All @@ -30,16 +59,20 @@ class HomeTestResultCellModel {
}

self?.configure(for: pcrTest.testResult)
onUpdate()
self?.onUpdate()
}
.store(in: &subscriptions)

coronaTestService.$pcrTestResultIsLoading
.receive(on: DispatchQueue.OCombine(.main))
.sink { [weak self] testResultIsLoading in
if testResultIsLoading && self?.coronaTestService.pcrTest?.finalTestResultReceivedDate == nil {
self?.configureLoading()
onUpdate()
if self?.coronaTestService.pcrTest?.finalTestResultReceivedDate == nil {
if testResultIsLoading {
self?.configureLoading()
} else if self?.isActivityIndicatorHidden == false {
self?.configureTestResultPending()
}
self?.onUpdate()
}
}
.store(in: &subscriptions)
Expand All @@ -58,16 +91,20 @@ class HomeTestResultCellModel {
}

self.configure(for: antigenTest.testResult)
onUpdate()
self.onUpdate()
}
.store(in: &subscriptions)

coronaTestService.$antigenTestResultIsLoading
.receive(on: DispatchQueue.OCombine(.main))
.sink { [weak self] testResultIsLoading in
if testResultIsLoading && self?.coronaTestService.antigenTest?.finalTestResultReceivedDate == nil {
self?.configureLoading()
onUpdate()
if self?.coronaTestService.antigenTest?.finalTestResultReceivedDate == nil {
if testResultIsLoading {
self?.configureLoading()
} else if self?.isActivityIndicatorHidden == false {
self?.configureTestResultPending()
}
self?.onUpdate()
}
}
.store(in: &subscriptions)
Expand All @@ -80,33 +117,12 @@ class HomeTestResultCellModel {
}

self?.configureTestResultOutdated()
onUpdate()
self?.onUpdate()
}
.store(in: &subscriptions)
}
}

// MARK: - Internal

@OpenCombine.Published var title: String! = ""
@OpenCombine.Published var subtitle: String?
@OpenCombine.Published var description: String! = ""
@OpenCombine.Published var footnote: String?
@OpenCombine.Published var buttonTitle: String! = ""
@OpenCombine.Published var image: UIImage?
@OpenCombine.Published var isDisclosureIndicatorHidden: Bool = false
@OpenCombine.Published var isNegativeDiagnosisHidden: Bool = true
@OpenCombine.Published var isActivityIndicatorHidden: Bool = false
@OpenCombine.Published var isUserInteractionEnabled: Bool = false
@OpenCombine.Published var isCellTappable: Bool = true
@OpenCombine.Published var accessibilityIdentifier: String! = AccessibilityIdentifiers.Home.submitCardButton

// MARK: - Private

private let coronaTestType: CoronaTestType
private let coronaTestService: CoronaTestService
private var subscriptions = Set<AnyCancellable>()

private func configure(for testResult: TestResult) {
#if DEBUG
if isUITesting {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class HomeTestResultCellModelTests: XCTestCase {
expectationIndicatorVisibility.expectedFulfillmentCount = indicatorVisibilityArray.count
expectationUserInteraction.expectedFulfillmentCount = userInteractionArray.count
expectationAccessibilityIdentifiers.expectedFulfillmentCount = accessibilityIdentifiersArray.count
expectationOnUpdate.expectedFulfillmentCount = accessibilityIdentifiersArray.count
expectationOnUpdate.expectedFulfillmentCount = 7

let coronaTestService = CoronaTestService(
client: ClientMock(),
Expand Down
38 changes: 35 additions & 3 deletions src/xcode/ENA/ENA/Source/Scenes/Home/HomeTableViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class HomeTableViewController: UITableViewController, NavigationBarOpacityDelega
setupTableView()

navigationItem.largeTitleDisplayMode = .automatic
tableView.backgroundColor = .enaColor(for: .separator)
tableView.backgroundColor = .enaColor(for: .darkBackground)

NotificationCenter.default.addObserver(self, selector: #selector(refreshUIAfterResumingFromBackground), name: UIApplication.willEnterForegroundNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(refreshUI), name: NSNotification.Name.NSCalendarDayChanged, object: nil)
Expand Down Expand Up @@ -181,15 +181,47 @@ class HomeTableViewController: UITableViewController, NavigationBarOpacityDelega
}

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
UIView()
guard HomeTableViewModel.Section(rawValue: section) == .settings else {
return UIView()
}

let headerView = UIView()
headerView.backgroundColor = .enaColor(for: .separator)

return headerView
}

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return viewModel.heightForHeader(in: section)
}

override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
UIView()
if HomeTableViewModel.Section(rawValue: section) == .infos {
let footerView = UIView()
footerView.backgroundColor = .enaColor(for: .separator)

return footerView
} else if HomeTableViewModel.Section(rawValue: section) == .settings {
let footerView = UIView()

let colorView = UIView()
colorView.backgroundColor = .enaColor(for: .separator)

footerView.addSubview(colorView)
colorView.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([
colorView.leadingAnchor.constraint(equalTo: footerView.leadingAnchor),
colorView.topAnchor.constraint(equalTo: footerView.topAnchor),
colorView.trailingAnchor.constraint(equalTo: footerView.trailingAnchor),
// Extend the last footer view so the color is shown even when rubber banding the scroll view
colorView.bottomAnchor.constraint(equalTo: footerView.bottomAnchor, constant: UIScreen.main.bounds.height)
])

return footerView
} else {
return UIView()
}
}

override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
Expand Down
Loading

0 comments on commit 687eed4

Please sign in to comment.