diff --git a/core/src/main/java/bisq/core/locale/CurrencyUtil.java b/core/src/main/java/bisq/core/locale/CurrencyUtil.java index e52fcb87932..c978c37510c 100644 --- a/core/src/main/java/bisq/core/locale/CurrencyUtil.java +++ b/core/src/main/java/bisq/core/locale/CurrencyUtil.java @@ -144,6 +144,17 @@ public static List getMainCryptoCurrencies() { return result; } + public static List getRemovedCryptoCurrencies() { + final List currencies = new ArrayList<>(); + currencies.add(new CryptoCurrency("BCH", "Bitcoin Cash")); + currencies.add(new CryptoCurrency("BCHC", "Bitcoin Clashic")); + currencies.add(new CryptoCurrency("ACH", "AchieveCoin")); + currencies.add(new CryptoCurrency("SC", "SpaceCash")); + currencies.add(new CryptoCurrency("PPI", "PiedPiper Coin")); + currencies.add(new CryptoCurrency("PEPECASH", "Pepe Cash")); + return currencies; + } + // At OKPay you can exchange internally those currencies public static List getAllAdvancedCashCurrencies() { ArrayList currencies = new ArrayList<>(Arrays.asList( @@ -388,7 +399,12 @@ public static String getNameByCode(String currencyCode) { if (isCryptoCurrency(currencyCode)) { // We might not find the name in case we have a call for a removed asset. // If BTC is the code (used in tests) we also want return Bitcoin as name. - String btcOrRemovedAsset = "BTC".equals(currencyCode) ? "Bitcoin" : Res.get("shared.na"); + final Optional removedCryptoCurrency = getRemovedCryptoCurrencies().stream() + .filter(cryptoCurrency -> cryptoCurrency.getCode().equals(currencyCode)) + .findAny(); + + String btcOrRemovedAsset = "BTC".equals(currencyCode) ? "Bitcoin" : + removedCryptoCurrency.isPresent() ? removedCryptoCurrency.get().getName() : Res.get("shared.na"); return getCryptoCurrency(currencyCode).map(TradeCurrency::getName).orElse(btcOrRemovedAsset); } try { diff --git a/core/src/test/java/bisq/core/locale/CurrencyUtilTest.java b/core/src/test/java/bisq/core/locale/CurrencyUtilTest.java index 1f4e52708d4..0623445d61d 100644 --- a/core/src/test/java/bisq/core/locale/CurrencyUtilTest.java +++ b/core/src/test/java/bisq/core/locale/CurrencyUtilTest.java @@ -19,6 +19,11 @@ import bisq.core.btc.BaseCurrencyNetwork; +import bisq.asset.Asset; +import bisq.asset.AssetRegistry; +import bisq.asset.Coin; +import bisq.asset.coins.Ether; + import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -34,18 +39,14 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; - - -import bisq.asset.Asset; -import bisq.asset.AssetRegistry; -import bisq.asset.Coin; -import bisq.asset.coins.Ether; - public class CurrencyUtilTest { @Before public void setup() { + Locale.setDefault(new Locale("en", "US")); + Res.setBaseCurrencyCode("BTC"); + Res.setBaseCurrencyName("Bitcoin"); } @Test @@ -128,6 +129,12 @@ public void testFindAsset() { assertEquals(Coin.Network.REGTEST, bsq.getNetwork()); } + @Test + public void testGetNameAndCodeOfRemovedAsset() { + assertEquals("Bitcoin Cash (BCH)", CurrencyUtil.getNameAndCode("BCH")); + assertEquals("N/A (XYZ)", CurrencyUtil.getNameAndCode("XYZ")); + } + class MockAssetRegistry extends AssetRegistry { private List registeredAssets = new ArrayList<>(); diff --git a/desktop/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModel.java b/desktop/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModel.java index 2054869aa06..ac6331d7293 100644 --- a/desktop/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModel.java +++ b/desktop/src/main/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModel.java @@ -129,6 +129,18 @@ public void applyOpenOffer(OpenOffer openOffer) { allowAmountUpdate = false; } + @Override + public boolean initWithData(OfferPayload.Direction direction, TradeCurrency tradeCurrency) { + try { + return super.initWithData(direction, tradeCurrency); + } catch (NullPointerException e) { + if (e.getMessage().contains("tradeCurrency")) { + throw new IllegalArgumentException("Offers of removed assets cannot be edited. You can only cancel it.", e); + } + return false; + } + } + @Override protected PaymentAccount getPreselectedPaymentAccount() { return paymentAccount; diff --git a/desktop/src/test/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModelTest.java b/desktop/src/test/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModelTest.java new file mode 100644 index 00000000000..82ab66a72ff --- /dev/null +++ b/desktop/src/test/java/bisq/desktop/main/portfolio/editoffer/EditOfferDataModelTest.java @@ -0,0 +1,127 @@ +package bisq.desktop.main.portfolio.editoffer; + +import bisq.desktop.util.validation.SecurityDepositValidator; + +import bisq.core.btc.model.AddressEntry; +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.btc.wallet.BtcWalletService; +import bisq.core.locale.Country; +import bisq.core.locale.CryptoCurrency; +import bisq.core.locale.GlobalSettings; +import bisq.core.locale.Res; +import bisq.core.offer.OfferPayload; +import bisq.core.offer.OpenOffer; +import bisq.core.payment.AccountAgeWitnessService; +import bisq.core.payment.CryptoCurrencyAccount; +import bisq.core.payment.PaymentAccount; +import bisq.core.provider.fee.FeeService; +import bisq.core.provider.price.MarketPrice; +import bisq.core.provider.price.PriceFeedService; +import bisq.core.user.Preferences; +import bisq.core.user.User; +import bisq.core.util.BSFormatter; +import bisq.core.util.BsqFormatter; +import bisq.core.util.validation.InputValidator; + +import org.bitcoinj.core.Coin; + +import javafx.beans.property.SimpleIntegerProperty; + +import javafx.collections.FXCollections; + +import java.time.Instant; + +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; + +import static bisq.desktop.maker.OfferMaker.btcBCHCOffer; +import static bisq.desktop.maker.PreferenceMakers.empty; +import static com.natpryce.makeiteasy.MakeItEasy.make; +import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({BtcWalletService.class, AddressEntry.class, PriceFeedService.class, User.class, + FeeService.class, PaymentAccount.class, BsqWalletService.class, + SecurityDepositValidator.class, AccountAgeWitnessService.class, BsqFormatter.class, Preferences.class, + BsqWalletService.class}) +@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"}) +public class EditOfferDataModelTest { + + private EditOfferDataModel model; + private User user; + + @Rule + public final ExpectedException exception = ExpectedException.none(); + + @Before + public void setUp() { + + final CryptoCurrency btc = new CryptoCurrency("BTC", "bitcoin"); + GlobalSettings.setDefaultTradeCurrency(btc); + Res.setup(); + + final BSFormatter bsFormatter = new BSFormatter(); + + FeeService feeService = mock(FeeService.class); + AddressEntry addressEntry = mock(AddressEntry.class); + BtcWalletService btcWalletService = mock(BtcWalletService.class); + PriceFeedService priceFeedService = mock(PriceFeedService.class); + user = mock(User.class); + PaymentAccount paymentAccount = mock(PaymentAccount.class); + Preferences preferences = mock(Preferences.class); + BsqFormatter bsqFormatter = mock(BsqFormatter.class); + BsqWalletService bsqWalletService = mock(BsqWalletService.class); + SecurityDepositValidator securityDepositValidator = mock(SecurityDepositValidator.class); + AccountAgeWitnessService accountAgeWitnessService = mock(AccountAgeWitnessService.class); + + when(btcWalletService.getOrCreateAddressEntry(anyString(), any())).thenReturn(addressEntry); + when(btcWalletService.getBalanceForAddress(any())).thenReturn(Coin.valueOf(1000L)); + when(priceFeedService.updateCounterProperty()).thenReturn(new SimpleIntegerProperty()); + when(priceFeedService.getMarketPrice(anyString())).thenReturn(new MarketPrice("USD", 12684.0450, Instant.now().getEpochSecond(), true)); + when(feeService.getTxFee(anyInt())).thenReturn(Coin.valueOf(1000L)); + when(user.findFirstPaymentAccountWithCurrency(any())).thenReturn(paymentAccount); + when(user.getPaymentAccountsAsObservable()).thenReturn(FXCollections.observableSet()); + when(securityDepositValidator.validate(any())).thenReturn(new InputValidator.ValidationResult(false)); + when(accountAgeWitnessService.getMyTradeLimit(any(), any())).thenReturn(100000000L); + when(preferences.getUserCountry()).thenReturn(new Country("US", "United States", null)); + when(bsqFormatter.formatCoin(any())).thenReturn("0"); + when(bsqWalletService.getAvailableBalance()).thenReturn(Coin.ZERO); + + model = new EditOfferDataModel(null, + btcWalletService, bsqWalletService, empty, user, + null, null, priceFeedService, null, + accountAgeWitnessService, null, feeService, + null, bsFormatter, null); + + } + + @Test + public void testEditOfferOfRemovedAsset() { + + final CryptoCurrencyAccount bitcoinClashicAccount = new CryptoCurrencyAccount(); + bitcoinClashicAccount.setId("BCHC"); + + when(user.getPaymentAccount(anyString())).thenReturn(bitcoinClashicAccount); + + model.applyOpenOffer(new OpenOffer(make(btcBCHCOffer), null)); + assertNull(model.getPreselectedPaymentAccount()); + } + + @Test + public void testInitializeEditOfferWithRemovedAsset() { + exception.expect(IllegalArgumentException.class); + model.initWithData(OfferPayload.Direction.BUY, null); + } +} diff --git a/desktop/src/test/java/bisq/desktop/maker/OfferMaker.java b/desktop/src/test/java/bisq/desktop/maker/OfferMaker.java index e620d1ba92b..e84f560f0b4 100644 --- a/desktop/src/test/java/bisq/desktop/maker/OfferMaker.java +++ b/desktop/src/test/java/bisq/desktop/maker/OfferMaker.java @@ -25,6 +25,7 @@ import com.natpryce.makeiteasy.Property; import static com.natpryce.makeiteasy.MakeItEasy.a; +import static com.natpryce.makeiteasy.MakeItEasy.with; public class OfferMaker { @@ -79,4 +80,5 @@ public class OfferMaker { 0)); public static final Maker btcUsdOffer = a(Offer); + public static final Maker btcBCHCOffer = a(Offer).but(with(counterCurrencyCode, "BCHC")); }