Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
12 changes: 6 additions & 6 deletions PayBack.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2245,7 +2245,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 128;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 39YTAJZTZ6;
ENABLE_STRICT_OBJC_MSGSEND = YES;
Expand All @@ -2267,7 +2267,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
MARKETING_VERSION = 0.1.12;
MARKETING_VERSION = 0.1.13;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
Expand Down Expand Up @@ -2315,7 +2315,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 128;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 39YTAJZTZ6;
ENABLE_NS_ASSERTIONS = NO;
Expand All @@ -2332,7 +2332,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
MARKETING_VERSION = 0.1.12;
MARKETING_VERSION = 0.1.13;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -2456,7 +2456,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 128;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 39YTAJZTZ6;
ENABLE_NS_ASSERTIONS = NO;
Expand All @@ -2473,7 +2473,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
MARKETING_VERSION = 0.1.12;
MARKETING_VERSION = 0.1.13;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down
16 changes: 10 additions & 6 deletions apps/ios/PayBack/Sources/Features/Activity/ExpenseDetailView.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import SwiftUI
import UIKit

enum SettlementErrorPresentation {
static let fallbackMessage = "We couldn't update this settlement. Please try again."

static func message(for error: Error?) -> String {
error?.userFacingMessage(fallback: fallbackMessage) ?? fallbackMessage
}
}

struct ExpenseDetailView: View {
@Environment(\.dismiss) private var dismiss
@EnvironmentObject var store: AppStore
Expand Down Expand Up @@ -102,9 +110,7 @@ struct ExpenseDetailView: View {
.alert("Unable to Update Settlement", isPresented: $showSettlementError) {
Button("OK", role: .cancel) { }
} message: {
Text(settlementError?.userFacingMessage(
fallback: "We couldn't update this settlement. Please try again."
) ?? "We couldn't update this settlement. Please try again.")
Text(SettlementErrorPresentation.message(for: settlementError))
}
}

Expand Down Expand Up @@ -557,9 +563,7 @@ struct SettleExpenseSheet: View {
.alert("Unable to Update Settlement", isPresented: $showSettlementError) {
Button("OK", role: .cancel) { }
} message: {
Text(settlementError?.userFacingMessage(
fallback: "We couldn't update this settlement. Please try again."
) ?? "We couldn't update this settlement. Please try again.")
Text(SettlementErrorPresentation.message(for: settlementError))
}
}
}
Expand Down
16 changes: 11 additions & 5 deletions apps/ios/PayBack/Tests/BusinessLogic/SettlementLogicTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,19 @@ final class SettlementLogicTests: XCTestCase {
XCTAssertFalse(settlementFunction.contains("Continue settling remaining expenses"))
}

func testExpenseSettlementAlertsSanitizeUnderlyingServerErrors() throws {
let source = try SourceFixture.contents(
at: "Sources/Features/Activity/ExpenseDetailView.swift"
func testExpenseSettlementAlertsSanitizeUnderlyingServerErrors() {
let rawError = PayBackError.underlying(
message: "[Request ID: private-request-id] internal server stack"
)

XCTAssertEqual(source.components(separatedBy: ".userFacingMessage(").count - 1, 2)
XCTAssertFalse(source.contains("settlementError?.errorDescription"))
XCTAssertEqual(
SettlementErrorPresentation.message(for: rawError),
"We couldn't update this settlement. Please try again."
)
XCTAssertEqual(
SettlementErrorPresentation.message(for: nil),
"We couldn't update this settlement. Please try again."
Comment on lines +33 to +39

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Exercise the alert binding in the sanitization regression

This now tests only SettlementErrorPresentation in isolation, so it still passes if either settlement alert later bypasses the helper and renders settlementError.errorDescription, which can expose the request ID and server stack used here. The replaced source assertion covered both alert sites; retain an Xcode Cloud-safe assertion that the actual alert presentation paths use the sanitizer rather than claiming alert-level coverage from the helper test alone.

AGENTS.md reference: AGENTS.md:L185-L190

Useful? React with 👍 / 👎.

)
}

func testTotalToSettleUsesCurrentUsersUnsettledShareInsteadOfExpenseTotal() {
Expand Down
4 changes: 2 additions & 2 deletions project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ settings:
base:
SWIFT_VERSION: "5.10"
IPHONEOS_DEPLOYMENT_TARGET: "18.0"
MARKETING_VERSION: 0.1.12
CURRENT_PROJECT_VERSION: 127
MARKETING_VERSION: 0.1.13
CURRENT_PROJECT_VERSION: 128
DEVELOPMENT_TEAM: "39YTAJZTZ6"
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS: YES
ENABLE_USER_SCRIPT_SANDBOXING: NO
Expand Down
Loading