Skip to content

Commit d9996ed

Browse files
committed
fix: preserve calculator btc on rate failure
1 parent 5ff1132 commit d9996ed

3 files changed

Lines changed: 28 additions & 12 deletions

File tree

Bitkit/Components/Widgets/CalculatorWidget.swift

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ struct CalculatorWidget: View {
271271
guard let source = values.refreshSource(activeInput: preferredSource) else { return }
272272

273273
if source == .fiat {
274-
refreshBitcoinFromFiat()
274+
refreshBitcoinFromFiat(preserveBitcoinOnConversionFailure: true)
275275
} else {
276276
refreshFiatFromBitcoin()
277277
}
@@ -296,20 +296,13 @@ struct CalculatorWidget: View {
296296
}
297297
}
298298

299-
private func refreshBitcoinFromFiat() {
299+
private func refreshBitcoinFromFiat(preserveBitcoinOnConversionFailure: Bool = false) {
300300
guard !values.fiatValue.isEmpty else {
301301
values.bitcoinValue = ""
302302
return
303303
}
304304

305-
let fiatValue = CalculatorWidgetFormatter.fiatDecimalValue(values.fiatValue)
306-
if NSDecimalNumber(decimal: fiatValue).compare(NSDecimalNumber.zero) == .orderedSame {
307-
values.bitcoinValue = CalculatorWidgetFormatter.fiatConversionBitcoinValue(0, displayUnit: currency.displayUnit)
308-
return
309-
}
310-
311-
let fiatDouble = NSDecimalNumber(decimal: fiatValue).doubleValue
312-
if let sats = currency.convert(fiatAmount: fiatDouble) {
305+
if let sats = CalculatorWidgetFormatter.convertedSatsFromFiat(values.fiatValue, convert: { currency.convert(fiatAmount: $0) }) {
313306
let cappedSats = min(sats, CalculatorWidgetFormatter.maxBitcoinSats)
314307
values.bitcoinValue = CalculatorWidgetFormatter.fiatConversionBitcoinValue(cappedSats, displayUnit: currency.displayUnit)
315308

@@ -320,9 +313,11 @@ struct CalculatorWidget: View {
320313
values.fiatValue = ""
321314
}
322315
}
323-
} else {
324-
values.bitcoinValue = ""
316+
return
325317
}
318+
319+
guard !preserveBitcoinOnConversionFailure else { return }
320+
values.bitcoinValue = ""
326321
}
327322

328323
private func persistValues() {

Bitkit/Models/CalculatorWidgetData.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,15 @@ enum CalculatorWidgetFormatter {
227227
sats == 0 ? "0" : satsToBitcoinValue(sats, displayUnit: displayUnit)
228228
}
229229

230+
static func convertedSatsFromFiat(_ rawValue: String, convert: (Double) -> UInt64?) -> UInt64? {
231+
let fiatValue = fiatDecimalValue(rawValue)
232+
if NSDecimalNumber(decimal: fiatValue).compare(NSDecimalNumber.zero) == .orderedSame {
233+
return 0
234+
}
235+
236+
return convert(NSDecimalNumber(decimal: fiatValue).doubleValue)
237+
}
238+
230239
static func fiatDecimalValue(_ rawValue: String) -> Decimal {
231240
decimalValue(sanitizeDecimalInput(raw: rawValue, maxDecimalPlaces: fiatDecimalPlaces))
232241
}

BitkitTests/CalculatorWidgetTests.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,18 @@ final class CalculatorWidgetTests: XCTestCase {
166166
XCTAssertEqual(CalculatorWidgetFormatter.fiatConversionBitcoinValue(0, displayUnit: .classic), "0")
167167
}
168168

169+
func testFiatConversionReturnsNilWhenRateUnavailable() {
170+
let sats = CalculatorWidgetFormatter.convertedSatsFromFiat("12.34") { _ in nil }
171+
172+
XCTAssertNil(sats)
173+
}
174+
175+
func testZeroFiatConversionDoesNotRequireRate() {
176+
let sats = CalculatorWidgetFormatter.convertedSatsFromFiat("0") { _ in nil }
177+
178+
XCTAssertEqual(sats, 0)
179+
}
180+
169181
func testClassicBitcoinRejectsValuesAboveSupply() {
170182
XCTAssertTrue(CalculatorWidgetFormatter.exceedsMaxBitcoin("21000000.00000001", displayUnit: .classic))
171183
XCTAssertFalse(CalculatorWidgetFormatter.exceedsMaxBitcoin("21000000", displayUnit: .classic))

0 commit comments

Comments
 (0)