This commit is contained in:
woodser 2021-05-04 20:20:01 -04:00
commit 8a38081c04
2800 changed files with 344130 additions and 0 deletions

View file

@ -0,0 +1,60 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop;
import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.FlowPane;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class AwesomeFontDemo extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
FlowPane flowPane = new FlowPane();
flowPane.setStyle("-fx-background-color: #ddd;");
flowPane.setHgap(2);
flowPane.setVgap(2);
List<AwesomeIcon> values = new ArrayList<>(Arrays.asList(AwesomeIcon.values()));
values.sort((o1, o2) -> o1.name().compareTo(o2.name()));
for (AwesomeIcon icon : values) {
Label label = new Label();
Button button = new Button(icon.name(), label);
button.setStyle("-fx-background-color: #fff;");
AwesomeDude.setIcon(label, icon, "12");
flowPane.getChildren().add(button);
}
primaryStage.setScene(new Scene(flowPane, 1200, 950));
primaryStage.show();
}
}

View file

@ -0,0 +1,9 @@
package bisq.desktop;
import javafx.application.Application;
public class AwesomeFontDemoLauncher {
public static void main(String[] args) {
Application.launch(AwesomeFontDemo.class);
}
}

View file

@ -0,0 +1,64 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop;
import bisq.desktop.components.AutoTooltipButton;
import bisq.desktop.components.AutoTooltipLabel;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BindingTest extends Application {
private static final Logger log = LoggerFactory.getLogger(BindingTest.class);
private static int counter = 0;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
VBox root = new VBox();
root.setSpacing(20);
Label label = new AutoTooltipLabel();
StringProperty txt = new SimpleStringProperty();
txt.set("-");
label.textProperty().bind(txt);
Button button = new AutoTooltipButton("count up");
button.setOnAction(e -> txt.set("counter " + counter++));
root.getChildren().addAll(label, button);
primaryStage.setScene(new Scene(root, 400, 400));
primaryStage.show();
}
}

View file

@ -0,0 +1,210 @@
package bisq.desktop;
import bisq.desktop.components.AutoTooltipLabel;
import bisq.desktop.components.FundsTextField;
import bisq.desktop.components.InfoInputTextField;
import bisq.desktop.components.InputTextField;
import bisq.desktop.components.TitledGroupBg;
import bisq.desktop.util.FormBuilder;
import bisq.desktop.util.Layout;
import bisq.core.locale.CryptoCurrency;
import bisq.core.locale.GlobalSettings;
import bisq.core.locale.Res;
import bisq.common.util.Tuple3;
import com.jfoenix.controls.JFXBadge;
import com.jfoenix.controls.JFXSnackbar;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.geometry.Pos;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import java.util.Locale;
import static bisq.desktop.util.FormBuilder.addFundsTextfield;
import static bisq.desktop.util.FormBuilder.addTopLabelInputTextFieldSlideToggleButton;
public class ComponentsDemo extends Application {
private JFXSnackbar bar;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
final CryptoCurrency btc = new CryptoCurrency("BTC", "bitcoin");
GlobalSettings.setDefaultTradeCurrency(btc);
GlobalSettings.setLocale(Locale.US);
Res.setup();
StackPane stackPane = new StackPane();
//MainView.rootContainer = stackPane;
bar = new JFXSnackbar(stackPane);
bar.setPrefWidth(450);
GridPane gridPane = new GridPane();
gridPane.getStyleClass().add("content-pane");
gridPane.setVgap(20);
int rowIndex = 0;
final TitledGroupBg helloGroup = FormBuilder.addTitledGroupBg(gridPane, rowIndex++, 4, "Hello Group", 20);
final Button button = FormBuilder.addButton(gridPane, rowIndex++, "Hello World");
button.setDisable(true);
button.getStyleClass().add("action-button");
Label label = new Label("PORTFOLIO");
label.setStyle("-fx-background-color: green");
final JFXBadge jfxBadge = new JFXBadge(label);
jfxBadge.setPosition(Pos.TOP_RIGHT);
jfxBadge.setPrefHeight(100);
jfxBadge.setMaxWidth(110);
final Button buttonEnabled = FormBuilder.addButton(gridPane, rowIndex++, "Hello World");
buttonEnabled.setOnMouseClicked((click) -> {
//bar.enqueue(new JFXSnackbar.SnackbarEvent(Res.get("notification.walletUpdate.msg", "0.345 BTC"), "CLOSE", 3000, true, b -> bar.close()));
// new Popup<>().headLine(Res.get("popup.roundedFiatValues.headline"))
// .message(Res.get("popup.roundedFiatValues.msg", "BTC"))
// .show();
// new Notification().headLine(Res.get("notification.tradeCompleted.headline"))
// .notification(Res.get("notification.tradeCompleted.msg"))
// .autoClose()
// .show();
jfxBadge.refreshBadge();
});
buttonEnabled.getStyleClass().add("action-button");
InputTextField inputTextField = FormBuilder.addInputTextField(gridPane, rowIndex++, "Enter something title");
inputTextField.setLabelFloat(true);
inputTextField.setText("Hello");
inputTextField.setPromptText("Enter something");
final Tuple3<HBox, InfoInputTextField, Label> editableValueBox = FormBuilder.getEditableValueBoxWithInfo("Please Enter!");
final HBox box = editableValueBox.first;
// box.setMaxWidth(243);
//box.setMaxWidth(200);
editableValueBox.third.setText("BTC");
editableValueBox.second.setContentForInfoPopOver(new Label("Hello World!"));
GridPane.setRowIndex(box, rowIndex++);
GridPane.setColumnIndex(box, 1);
gridPane.getChildren().add(box);
final FundsTextField fundsTextField = addFundsTextfield(gridPane, rowIndex++,
"Total Needed", Layout.FIRST_ROW_AND_GROUP_DISTANCE);
//fundsTextField.setText("Hello World");
final ComboBox<String> comboBox = FormBuilder.<String>addTopLabelComboBox(gridPane, rowIndex++, "Numbers", "Select currency", 0).second;
ObservableList list = FXCollections.observableArrayList();
list.addAll("EUR", "USD", "GBP");
comboBox.setItems(list);
/*comboBox.setButtonCell(new ListCell<>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
this.setVisible(item != null || !empty);
if (item != null && !empty) {
AnchorPane pane = new AnchorPane();
Label currency = new AutoTooltipLabel(item + " - US Dollar");
currency.getStyleClass().add("currency-label-selected");
AnchorPane.setLeftAnchor(currency, 0.0);
Label numberOfOffers = new AutoTooltipLabel("21 offers");
numberOfOffers.getStyleClass().add("offer-label-small");
AnchorPane.setRightAnchor(numberOfOffers, 0.0);
AnchorPane.setBottomAnchor(numberOfOffers, 0.0);
pane.getChildren().addAll(currency, numberOfOffers);
setGraphic(pane);
setText("");
} else {
setGraphic(null);
setText("");
}
}
});*/
comboBox.setCellFactory(p -> new ListCell<>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty) {
HBox box = new HBox();
box.setSpacing(20);
Label currencyType = new AutoTooltipLabel("Crypto");
currencyType.getStyleClass().add("currency-label-small");
Label currency = new AutoTooltipLabel(item);
currency.getStyleClass().add("currency-label");
Label offers = new AutoTooltipLabel("Euro (21 offers)");
offers.getStyleClass().add("currency-label");
box.getChildren().addAll(currencyType, currency, offers);
setGraphic(box);
} else {
setGraphic(null);
}
}
});
Label xLabel = new Label();
// xLabel.getStyleClass().add("opaque-icon");
//final Text icon = getIconForLabel(MaterialDesignIcon.CLOSE, "2em", xLabel);
//final Text icon = getIconForLabel(MaterialDesignIcon.CLOSE, "2em", xLabel);
/*icon.getStyleClass().add("opaque-icon");
GridPane.setRowIndex(xLabel, rowIndex++);
GridPane.setColumnIndex(xLabel, 0);
gridPane.getChildren().add(xLabel);*/
// FlowPane iconsPane = new FlowPane(3,3);
// for (MaterialDesignIcon ic : MaterialDesignIcon.values()) {
// iconsPane.getChildren().add(new MaterialDesignIconView(ic, "3em"));
// }
//
// GridPane.setRowIndex(iconsPane, rowIndex++);
// gridPane.getChildren().add(iconsPane);
jfxBadge.setText("2");
// jfxBadge.setEnabled(false);
GridPane.setRowIndex(jfxBadge, rowIndex++);
GridPane.setColumnIndex(jfxBadge, 0);
gridPane.getChildren().add(jfxBadge);
Tuple3<Label, InputTextField, ToggleButton> tuple = addTopLabelInputTextFieldSlideToggleButton(gridPane, ++rowIndex,
Res.get("setting.preferences.txFee"), Res.get("setting.preferences.useCustomValue"));
tuple.second.setDisable(true);
FormBuilder.addInputTextField(gridPane, ++rowIndex, Res.get("setting.preferences.deviation"));
final ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(gridPane);
stackPane.getChildren().add(scrollPane);
Scene scene = new Scene(stackPane, 1000, 650);
scene.getStylesheets().setAll(
"/bisq/desktop/bisq.css",
"/bisq/desktop/images.css");
primaryStage.setScene(scene);
primaryStage.show();
}
}

View file

@ -0,0 +1,9 @@
package bisq.desktop;
import javafx.application.Application;
public class ComponentsDemoLauncher {
public static void main(String[] args) {
Application.launch(ComponentsDemo.class);
}
}

View file

@ -0,0 +1,161 @@
package bisq.desktop;
import bisq.desktop.app.BisqAppModule;
import bisq.desktop.common.view.CachingViewLoader;
import bisq.desktop.common.view.ViewLoader;
import bisq.desktop.common.view.guice.InjectorViewFactory;
import bisq.desktop.main.dao.bonding.BondingViewUtils;
import bisq.desktop.main.funds.transactions.DisplayedTransactionsFactory;
import bisq.desktop.main.funds.transactions.TradableRepository;
import bisq.desktop.main.funds.transactions.TransactionAwareTradableFactory;
import bisq.desktop.main.funds.transactions.TransactionListItemFactory;
import bisq.desktop.main.offer.offerbook.OfferBook;
import bisq.desktop.main.overlays.notifications.NotificationCenter;
import bisq.desktop.main.overlays.windows.TorNetworkSettingsWindow;
import bisq.desktop.main.presentation.DaoPresentation;
import bisq.desktop.main.presentation.MarketPricePresentation;
import bisq.desktop.util.Transitions;
import bisq.core.app.AvoidStandbyModeService;
import bisq.core.app.P2PNetworkSetup;
import bisq.core.app.TorSetup;
import bisq.core.app.WalletAppSetup;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.network.p2p.seed.DefaultSeedNodeRepository;
import bisq.core.notifications.MobileMessageEncryption;
import bisq.core.notifications.MobileModel;
import bisq.core.notifications.MobileNotificationService;
import bisq.core.notifications.MobileNotificationValidator;
import bisq.core.notifications.alerts.MyOfferTakenEvents;
import bisq.core.notifications.alerts.TradeEvents;
import bisq.core.notifications.alerts.market.MarketAlerts;
import bisq.core.notifications.alerts.price.PriceAlert;
import bisq.core.payment.ChargeBackRisk;
import bisq.core.payment.TradeLimits;
import bisq.core.proto.network.CoreNetworkProtoResolver;
import bisq.core.proto.persistable.CorePersistenceProtoResolver;
import bisq.core.support.dispute.arbitration.ArbitrationDisputeListService;
import bisq.core.support.dispute.arbitration.ArbitrationManager;
import bisq.core.support.dispute.arbitration.arbitrator.ArbitratorManager;
import bisq.core.support.dispute.arbitration.arbitrator.ArbitratorService;
import bisq.core.support.dispute.mediation.MediationDisputeListService;
import bisq.core.support.dispute.mediation.MediationManager;
import bisq.core.support.dispute.mediation.mediator.MediatorManager;
import bisq.core.support.dispute.mediation.mediator.MediatorService;
import bisq.core.support.traderchat.TraderChatManager;
import bisq.core.user.Preferences;
import bisq.core.user.User;
import bisq.core.util.coin.BsqFormatter;
import bisq.network.p2p.network.BridgeAddressProvider;
import bisq.network.p2p.seed.SeedNodeRepository;
import bisq.common.ClockWatcher;
import bisq.common.config.Config;
import bisq.common.crypto.KeyRing;
import bisq.common.crypto.KeyStorage;
import bisq.common.crypto.PubKeyRing;
import bisq.common.file.CorruptedStorageFileHandler;
import bisq.common.persistence.PersistenceManager;
import bisq.common.proto.network.NetworkProtoResolver;
import bisq.common.proto.persistable.PersistenceProtoResolver;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.junit.Before;
import org.junit.Test;
import static junit.framework.TestCase.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
public class GuiceSetupTest {
private Injector injector;
@Before
public void setUp() {
Res.setup();
CurrencyUtil.setup();
injector = Guice.createInjector(new BisqAppModule(new Config()));
}
@Test
public void testGuiceSetup() {
injector.getInstance(AvoidStandbyModeService.class);
// desktop module
assertSingleton(OfferBook.class);
assertSingleton(CachingViewLoader.class);
assertSingleton(Navigation.class);
assertSingleton(InjectorViewFactory.class);
assertSingleton(NotificationCenter.class);
assertSingleton(BsqFormatter.class);
assertSingleton(TorNetworkSettingsWindow.class);
assertSingleton(MarketPricePresentation.class);
assertSingleton(ViewLoader.class);
assertSingleton(DaoPresentation.class);
assertSingleton(Transitions.class);
assertSingleton(TradableRepository.class);
assertSingleton(TransactionListItemFactory.class);
assertSingleton(TransactionAwareTradableFactory.class);
assertSingleton(DisplayedTransactionsFactory.class);
assertSingleton(BondingViewUtils.class);
// core module
// assertSingleton(BisqSetup.class); // this is a can of worms
// assertSingleton(DisputeMsgEvents.class);
assertSingleton(TorSetup.class);
assertSingleton(P2PNetworkSetup.class);
assertSingleton(WalletAppSetup.class);
assertSingleton(TradeLimits.class);
assertSingleton(KeyStorage.class);
assertSingleton(KeyRing.class);
assertSingleton(PubKeyRing.class);
assertSingleton(User.class);
assertSingleton(ClockWatcher.class);
assertSingleton(Preferences.class);
assertSingleton(BridgeAddressProvider.class);
assertSingleton(CorruptedStorageFileHandler.class);
assertSingleton(AvoidStandbyModeService.class);
assertSingleton(DefaultSeedNodeRepository.class);
assertSingleton(SeedNodeRepository.class);
assertTrue(injector.getInstance(SeedNodeRepository.class) instanceof DefaultSeedNodeRepository);
assertSingleton(CoreNetworkProtoResolver.class);
assertSingleton(NetworkProtoResolver.class);
assertTrue(injector.getInstance(NetworkProtoResolver.class) instanceof CoreNetworkProtoResolver);
assertSingleton(PersistenceProtoResolver.class);
assertSingleton(CorePersistenceProtoResolver.class);
assertTrue(injector.getInstance(PersistenceProtoResolver.class) instanceof CorePersistenceProtoResolver);
assertSingleton(MobileMessageEncryption.class);
assertSingleton(MobileNotificationService.class);
assertSingleton(MobileNotificationValidator.class);
assertSingleton(MobileModel.class);
assertSingleton(MyOfferTakenEvents.class);
assertSingleton(TradeEvents.class);
assertSingleton(PriceAlert.class);
assertSingleton(MarketAlerts.class);
assertSingleton(ChargeBackRisk.class);
assertSingleton(ArbitratorService.class);
assertSingleton(ArbitratorManager.class);
assertSingleton(ArbitrationManager.class);
assertSingleton(ArbitrationDisputeListService.class);
assertSingleton(MediatorService.class);
assertSingleton(MediatorManager.class);
assertSingleton(MediationManager.class);
assertSingleton(MediationDisputeListService.class);
assertSingleton(TraderChatManager.class);
assertNotSingleton(PersistenceManager.class);
}
private void assertSingleton(Class<?> type) {
assertSame(injector.getInstance(type), injector.getInstance(type));
}
private void assertNotSingleton(Class<?> type) {
assertNotSame(injector.getInstance(type), injector.getInstance(type));
}
}

View file

@ -0,0 +1,78 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop;
import bisq.core.locale.CryptoCurrency;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.FiatCurrency;
import java.util.Collection;
import java.util.Comparator;
import java.util.Locale;
import java.util.stream.Stream;
public class MarketsPrintTool {
public static void main(String[] args) {
// Prints out all coins in the format used in the market_currency_selector.html.
// Run that and copy paste the result to the market_currency_selector.html at new releases.
StringBuilder sb = new StringBuilder();
Locale.setDefault(new Locale("en", "US"));
// <option value="onion_btc">DeepOnion (ONION)</option>
// <option value="btc_bhd">Bahraini Dinar (BHD)</option>
final Collection<FiatCurrency> allSortedFiatCurrencies = CurrencyUtil.getAllSortedFiatCurrencies();
final Stream<MarketCurrency> fiatStream = allSortedFiatCurrencies.stream()
.filter(e -> !e.getCurrency().getCurrencyCode().equals("BSQ"))
.filter(e -> !e.getCurrency().getCurrencyCode().equals("BTC"))
.map(e -> new MarketCurrency("btc_" + e.getCode().toLowerCase(), e.getName(), e.getCode()))
.distinct();
final Collection<CryptoCurrency> allSortedCryptoCurrencies = CurrencyUtil.getAllSortedCryptoCurrencies();
final Stream<MarketCurrency> cryptoStream = allSortedCryptoCurrencies.stream()
.filter(e -> !e.getCode().equals("BTC"))
.map(e -> new MarketCurrency(e.getCode().toLowerCase() + "_btc", e.getName(), e.getCode()))
.distinct();
Stream.concat(fiatStream, cryptoStream)
.sorted(Comparator.comparing(o -> o.currencyName.toLowerCase()))
.distinct()
.forEach(e -> sb.append("<option value=\"")
.append(e.marketSelector)
.append("\">")
.append(e.currencyName)
.append(" (")
.append(e.currencyCode)
.append(")</option>")
.append("\n"));
System.out.println(sb.toString());
}
private static class MarketCurrency {
final String marketSelector;
final String currencyName;
final String currencyCode;
MarketCurrency(String marketSelector, String currencyName, String currencyCode) {
this.marketSelector = marketSelector;
this.currencyName = currencyName;
this.currencyCode = currencyCode;
}
}
}

View file

@ -0,0 +1,63 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop;
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon;
import de.jensd.fx.glyphs.materialdesignicons.utils.MaterialDesignIconFactory;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.FlowPane;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class MaterialDesignIconDemo extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
ScrollPane scrollPane = new ScrollPane();
scrollPane.setFitToWidth(true);
FlowPane flowPane = new FlowPane();
flowPane.setStyle("-fx-background-color: #ddd;");
flowPane.setHgap(2);
flowPane.setVgap(2);
List<MaterialDesignIcon> values = new ArrayList<>(Arrays.asList(MaterialDesignIcon.values()));
values.sort(Comparator.comparing(Enum::name));
for (MaterialDesignIcon icon : values) {
Button button = MaterialDesignIconFactory.get().createIconButton(icon, icon.name());
flowPane.getChildren().add(button);
}
scrollPane.setContent(flowPane);
primaryStage.setScene(new Scene(scrollPane, 1200, 950));
primaryStage.show();
}
}

View file

@ -0,0 +1,26 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop;
import javafx.application.Application;
public class MaterialDesignIconDemoLauncher {
public static void main(String[] args) {
Application.launch(MaterialDesignIconDemo.class);
}
}

View file

@ -0,0 +1,20 @@
<!--
~ This file is part of Bisq.
~
~ Bisq is free software: you can redistribute it and/or modify it
~ under the terms of the GNU Affero General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or (at
~ your option) any later version.
~
~ Bisq is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
~ License for more details.
~
~ You should have received a copy of the GNU Affero General Public License
~ along with Bisq. If not, see <http://www.gnu.org/licenses/>.
-->
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane xmlns:fx="http://javafx.com/fxml">
</AnchorPane>

View file

@ -0,0 +1,21 @@
<!--
~ This file is part of Bisq.
~
~ Bisq is free software: you can redistribute it and/or modify it
~ under the terms of the GNU Affero General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or (at
~ your option) any later version.
~
~ Bisq is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
~ License for more details.
~
~ You should have received a copy of the GNU Affero General Public License
~ along with Bisq. If not, see <http://www.gnu.org/licenses/>.
-->
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="root" fx:controller="bisq.desktop.common.fxml.FxmlViewLoaderTests$MissingFxmlViewAnnotation"
xmlns:fx="http://javafx.com/fxml">
</AnchorPane>

View file

@ -0,0 +1,21 @@
<!--
~ This file is part of Bisq.
~
~ Bisq is free software: you can redistribute it and/or modify it
~ under the terms of the GNU Affero General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or (at
~ your option) any later version.
~
~ Bisq is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
~ License for more details.
~
~ You should have received a copy of the GNU Affero General Public License
~ along with Bisq. If not, see <http://www.gnu.org/licenses/>.
-->
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="root" fx:controller="bisq.desktop.common.fxml.FxmlViewLoaderTests$WellFormed"
xmlns:fx="http://javafx.com/fxml">
</AnchorPane>

View file

@ -0,0 +1,133 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.common.fxml;
import bisq.desktop.common.ViewfxException;
import bisq.desktop.common.view.AbstractView;
import bisq.desktop.common.view.FxmlView;
import bisq.desktop.common.view.View;
import bisq.desktop.common.view.ViewFactory;
import bisq.desktop.common.view.ViewLoader;
import javafx.fxml.LoadException;
import java.util.ResourceBundle;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
// TODO Some refactorings seem to have broken those tests. Investigate and remove @Ignore as soon its fixed.
@Ignore
public class FxmlViewLoaderTests {
private ViewLoader viewLoader;
private ViewFactory viewFactory;
@Rule
public ExpectedException thrown = ExpectedException.none();
@Before
public void setUp() {
viewFactory = mock(ViewFactory.class);
ResourceBundle resourceBundle = mock(ResourceBundle.class);
viewLoader = new FxmlViewLoader(viewFactory, resourceBundle);
}
@FxmlView
public static class WellFormed extends AbstractView {
}
@Test
public void wellFormedFxmlFileShouldSucceed() {
given(viewFactory.call(WellFormed.class)).willReturn(new WellFormed());
View view = viewLoader.load(WellFormed.class);
assertThat(view, instanceOf(WellFormed.class));
}
@FxmlView
public static class MissingFxController extends AbstractView {
}
@Test
public void fxmlFileMissingFxControllerAttributeShouldThrow() {
thrown.expect(ViewfxException.class);
thrown.expectMessage("Does it declare an fx:controller attribute?");
viewLoader.load(MissingFxController.class);
}
public static class MissingFxmlViewAnnotation extends AbstractView {
}
@Test
public void fxmlViewAnnotationShouldBeOptional() {
given(viewFactory.call(MissingFxmlViewAnnotation.class)).willReturn(new MissingFxmlViewAnnotation());
View view = viewLoader.load(MissingFxmlViewAnnotation.class);
assertThat(view, instanceOf(MissingFxmlViewAnnotation.class));
}
@FxmlView
public static class Malformed extends AbstractView {
}
@Test
public void malformedFxmlFileShouldThrow() {
thrown.expect(ViewfxException.class);
thrown.expectMessage("Failed to load view from FXML file");
thrown.expectCause(instanceOf(LoadException.class));
viewLoader.load(Malformed.class);
}
@FxmlView
public static class MissingFxmlFile extends AbstractView {
}
@Test
public void missingFxmlFileShouldThrow() {
thrown.expect(ViewfxException.class);
thrown.expectMessage("Does it exist?");
viewLoader.load(MissingFxmlFile.class);
}
@FxmlView(location = "unconventionally/located.fxml")
public static class CustomLocation extends AbstractView {
}
@Test
public void customFxmlFileLocationShouldOverrideDefaultConvention() {
thrown.expect(ViewfxException.class);
thrown.expectMessage("Failed to load view class");
thrown.expectMessage("CustomLocation");
thrown.expectMessage("[unconventionally/located.fxml] could not be loaded");
viewLoader.load(CustomLocation.class);
}
}

View file

@ -0,0 +1,56 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.common.support;
import bisq.desktop.common.view.AbstractView;
import bisq.desktop.common.view.CachingViewLoader;
import bisq.desktop.common.view.ViewLoader;
import org.junit.Test;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
public class CachingViewLoaderTests {
@Test
public void test() {
ViewLoader delegateViewLoader = mock(ViewLoader.class);
ViewLoader cachingViewLoader = new CachingViewLoader(delegateViewLoader);
cachingViewLoader.load(TestView1.class);
cachingViewLoader.load(TestView1.class);
cachingViewLoader.load(TestView2.class);
then(delegateViewLoader).should(times(1)).load(TestView1.class);
then(delegateViewLoader).should(times(1)).load(TestView2.class);
then(delegateViewLoader).should(times(0)).load(TestView3.class);
}
static class TestView1 extends AbstractView {
}
static class TestView2 extends AbstractView {
}
static class TestView3 extends AbstractView {
}
}

View file

@ -0,0 +1,79 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.components;
import javafx.scene.control.Label;
import javafx.scene.text.Text;
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;
public class ColoredDecimalPlacesWithZerosTextTest {
@Ignore
public void testOnlyZeroDecimals() {
ColoredDecimalPlacesWithZerosText text = new ColoredDecimalPlacesWithZerosText("1.0000", 3);
Label beforeZeros = (Label) text.getChildren().get(0);
Label zeroDecimals = (Label) text.getChildren().get(1);
assertEquals("1.0", beforeZeros.getText());
assertEquals("000", zeroDecimals.getText());
}
@Ignore
public void testOneZeroDecimal() {
ColoredDecimalPlacesWithZerosText text = new ColoredDecimalPlacesWithZerosText("1.2570", 3);
Text beforeZeros = (Text) text.getChildren().get(0);
Text zeroDecimals = (Text) text.getChildren().get(1);
assertEquals("1.257", beforeZeros.getText());
assertEquals("0", zeroDecimals.getText());
}
@Ignore
public void testMultipleZeroDecimal() {
ColoredDecimalPlacesWithZerosText text = new ColoredDecimalPlacesWithZerosText("1.2000", 3);
Text beforeZeros = (Text) text.getChildren().get(0);
Text zeroDecimals = (Text) text.getChildren().get(1);
assertEquals("1.2", beforeZeros.getText());
assertEquals("000", zeroDecimals.getText());
}
@Ignore
public void testZeroDecimalsWithRange() {
ColoredDecimalPlacesWithZerosText text = new ColoredDecimalPlacesWithZerosText("0.1000 - 0.1250", 3);
assertEquals(5, text.getChildren().size());
Text beforeZeros = (Text) text.getChildren().get(0);
Text zeroDecimals = (Text) text.getChildren().get(1);
Text separator = (Text) text.getChildren().get(2);
Text beforeZeros2 = (Text) text.getChildren().get(3);
Text zeroDecimals2 = (Text) text.getChildren().get(4);
assertEquals("0.1", beforeZeros.getText());
assertEquals("000", zeroDecimals.getText());
assertEquals(" - ", separator.getText());
assertEquals("0.125", beforeZeros2.getText());
assertEquals("0", zeroDecimals2.getText());
}
@Ignore
public void testNoColorizing() {
ColoredDecimalPlacesWithZerosText text = new ColoredDecimalPlacesWithZerosText("1.2570", 0);
Text beforeZeros = (Text) text.getChildren().get(0);
assertEquals("1.2570", beforeZeros.getText());
}
}

View file

@ -0,0 +1,63 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.main.dao.monitor.daostate;
import bisq.core.dao.monitoring.model.DaoStateBlock;
import bisq.core.dao.monitoring.model.DaoStateHash;
import bisq.core.locale.Res;
import java.util.Locale;
import java.util.function.IntSupplier;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
public class DaoStateBlockListItemTest {
@Before
public void setup() {
Locale.setDefault(new Locale("en", "US"));
Res.setBaseCurrencyCode("BTC");
Res.setBaseCurrencyName("Bitcoin");
}
@Test
public void testEqualsAndHashCode() {
var block = new DaoStateBlock(new DaoStateHash(0, new byte[0], new byte[0]));
var item1 = new DaoStateBlockListItem(block, newSupplier(1));
var item2 = new DaoStateBlockListItem(block, newSupplier(2));
var item3 = new DaoStateBlockListItem(block, newSupplier(1));
assertNotEquals(item1, item2);
assertNotEquals(item2, item3);
assertEquals(item1, item3);
assertEquals(item1.hashCode(), item3.hashCode());
}
private IntSupplier newSupplier(int i) {
//noinspection Convert2Lambda
return new IntSupplier() {
@Override
public int getAsInt() {
return i;
}
};
}
}

View file

@ -0,0 +1,82 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.main.funds.transactions;
import bisq.core.btc.wallet.BtcWalletService;
import org.bitcoinj.core.Transaction;
import com.google.common.collect.Sets;
import javafx.collections.FXCollections;
import java.util.Collections;
import java.util.Set;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;
public class DisplayedTransactionsTest {
@Test
public void testUpdate() {
Set<Transaction> transactions = Sets.newHashSet(mock(Transaction.class), mock(Transaction.class));
BtcWalletService walletService = mock(BtcWalletService.class);
when(walletService.getTransactions(false)).thenReturn(transactions);
TransactionListItemFactory transactionListItemFactory = mock(TransactionListItemFactory.class,
RETURNS_DEEP_STUBS);
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
DisplayedTransactions testedEntity = new DisplayedTransactions(
walletService,
mock(TradableRepository.class),
transactionListItemFactory,
mock(TransactionAwareTradableFactory.class));
testedEntity.update();
assertEquals(transactions.size(), testedEntity.size());
}
@Test
public void testUpdateWhenRepositoryIsEmpty() {
BtcWalletService walletService = mock(BtcWalletService.class);
when(walletService.getTransactions(false))
.thenReturn(Collections.singleton(mock(Transaction.class)));
TradableRepository tradableRepository = mock(TradableRepository.class);
when(tradableRepository.getAll()).thenReturn(FXCollections.emptyObservableSet());
TransactionListItemFactory transactionListItemFactory = mock(TransactionListItemFactory.class);
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
DisplayedTransactions testedEntity = new DisplayedTransactions(
walletService,
tradableRepository,
transactionListItemFactory,
mock(TransactionAwareTradableFactory.class));
testedEntity.update();
assertEquals(1, testedEntity.size());
verify(transactionListItemFactory).create(any(), nullable(TransactionAwareTradable.class));
}
}

View file

@ -0,0 +1,55 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.main.funds.transactions;
import com.google.common.collect.Lists;
import java.util.Collection;
import java.util.function.Supplier;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
public class ObservableListDecoratorTest {
@Test
public void testSetAll() {
ObservableListDecorator<Integer> list = new ObservableListDecorator<>();
Collection<Integer> state = Lists.newArrayList(3, 2, 1);
list.setAll(state);
assertEquals(state, list);
state = Lists.newArrayList(0, 0, 0, 0);
list.setAll(state);
assertEquals(state, list);
}
@Test
public void testForEach() {
ObservableListDecorator<Supplier> list = new ObservableListDecorator<>();
Collection<Supplier> state = Lists.newArrayList(mock(Supplier.class), mock(Supplier.class));
list.setAll(state);
assertEquals(state, list);
list.forEach(Supplier::get);
state.forEach(supplier -> verify(supplier).get());
}
}

View file

@ -0,0 +1,48 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.main.funds.transactions;
import bisq.core.offer.OpenOffer;
import bisq.core.support.dispute.arbitration.ArbitrationManager;
import bisq.core.trade.Tradable;
import bisq.core.trade.Trade;
import org.bitcoinj.core.Transaction;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.mockito.Mockito.mock;
public class TransactionAwareTradableFactoryTest {
@Test
public void testCreateWhenNotOpenOfferOrTrade() {
ArbitrationManager arbitrationManager = mock(ArbitrationManager.class);
TransactionAwareTradableFactory factory = new TransactionAwareTradableFactory(arbitrationManager,
null, null, null);
Tradable delegate = mock(Tradable.class);
assertFalse(delegate instanceof OpenOffer);
assertFalse(delegate instanceof Trade);
TransactionAwareTradable tradable = factory.create(delegate);
assertFalse(tradable.isRelatedToTransaction(mock(Transaction.class)));
}
}

View file

@ -0,0 +1,105 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.main.funds.transactions;
import bisq.core.btc.wallet.BtcWalletService;
import bisq.core.support.dispute.Dispute;
import bisq.core.support.dispute.arbitration.ArbitrationManager;
import bisq.core.support.dispute.refund.RefundManager;
import bisq.core.trade.Trade;
import org.bitcoinj.core.Sha256Hash;
import org.bitcoinj.core.Transaction;
import javafx.collections.FXCollections;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class TransactionAwareTradeTest {
private static final Sha256Hash XID = Sha256Hash.wrap("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef");
private Transaction transaction;
private ArbitrationManager arbitrationManager;
private Trade delegate;
private TransactionAwareTradable trade;
private RefundManager refundManager;
private BtcWalletService btcWalletService;
@Before
public void setUp() {
this.transaction = mock(Transaction.class);
when(transaction.getTxId()).thenReturn(XID);
delegate = mock(Trade.class, RETURNS_DEEP_STUBS);
arbitrationManager = mock(ArbitrationManager.class, RETURNS_DEEP_STUBS);
refundManager = mock(RefundManager.class, RETURNS_DEEP_STUBS);
btcWalletService = mock(BtcWalletService.class, RETURNS_DEEP_STUBS);
trade = new TransactionAwareTrade(delegate, arbitrationManager, refundManager, btcWalletService, null);
}
@Test
public void testIsRelatedToTransactionWhenTakerOfferFeeTx() {
when(delegate.getTakerFeeTxId()).thenReturn(XID.toString());
assertTrue(trade.isRelatedToTransaction(transaction));
}
@Test
public void testIsRelatedToTransactionWhenPayoutTx() {
when(delegate.getPayoutTx().getTxId()).thenReturn(XID);
assertTrue(trade.isRelatedToTransaction(transaction));
}
@Test
public void testIsRelatedToTransactionWhenDepositTx() {
when(delegate.getDepositTx().getTxId()).thenReturn(XID);
assertTrue(trade.isRelatedToTransaction(transaction));
}
@Test
public void testIsRelatedToTransactionWhenOfferFeeTx() {
when(delegate.getOffer().getOfferFeePaymentTxId()).thenReturn(XID.toString());
assertTrue(trade.isRelatedToTransaction(transaction));
}
@Test
public void testIsRelatedToTransactionWhenDisputedPayoutTx() {
final String tradeId = "7";
Dispute dispute = mock(Dispute.class);
when(dispute.getDisputePayoutTxId()).thenReturn(XID.toString());
when(dispute.getTradeId()).thenReturn(tradeId);
when(arbitrationManager.getDisputesAsObservableList())
.thenReturn(FXCollections.observableArrayList(Set.of(dispute)));
when(arbitrationManager.getDisputedTradeIds())
.thenReturn(Set.of(tradeId));
when(delegate.getId()).thenReturn(tradeId);
assertTrue(trade.isRelatedToTransaction(transaction));
}
}

View file

@ -0,0 +1,208 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.main.market.offerbook;
import bisq.desktop.main.offer.offerbook.OfferBook;
import bisq.desktop.main.offer.offerbook.OfferBookListItem;
import bisq.desktop.main.offer.offerbook.OfferBookListItemMaker;
import bisq.core.locale.GlobalSettings;
import bisq.core.provider.price.PriceFeedService;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import org.junit.Before;
import org.junit.Test;
import static bisq.desktop.main.offer.offerbook.OfferBookListItemMaker.btcBuyItem;
import static bisq.desktop.main.offer.offerbook.OfferBookListItemMaker.btcSellItem;
import static bisq.desktop.maker.PreferenceMakers.empty;
import static bisq.desktop.maker.TradeCurrencyMakers.usd;
import static com.natpryce.makeiteasy.MakeItEasy.make;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class OfferBookChartViewModelTest {
@Before
public void setUp() {
GlobalSettings.setDefaultTradeCurrency(usd);
}
@Test
public void testMaxCharactersForBuyPriceWithNoOffers() {
OfferBook offerBook = mock(OfferBook.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookChartViewModel model = new OfferBookChartViewModel(offerBook, empty, null, null, null);
assertEquals(0, model.maxPlacesForBuyPrice.intValue());
}
@Test
public void testMaxCharactersForBuyPriceWithOfflinePriceFeedService() {
OfferBook offerBook = mock(OfferBook.class);
PriceFeedService priceFeedService = mock(PriceFeedService.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
final OfferBookListItem item = make(OfferBookListItemMaker.btcBuyItem.but(with(OfferBookListItemMaker.useMarketBasedPrice, true)));
item.getOffer().setPriceFeedService(priceFeedService);
offerBookListItems.addAll(item);
when(priceFeedService.getMarketPrice(anyString())).thenReturn(null);
when(priceFeedService.updateCounterProperty()).thenReturn(new SimpleIntegerProperty());
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookChartViewModel model = new OfferBookChartViewModel(offerBook, empty, priceFeedService, null, null);
model.activate();
assertEquals(0, model.maxPlacesForBuyPrice.intValue());
}
@Test
public void testMaxCharactersForFiatBuyPrice() {
OfferBook offerBook = mock(OfferBook.class);
PriceFeedService service = mock(PriceFeedService.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
offerBookListItems.addAll(make(OfferBookListItemMaker.btcBuyItem));
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookChartViewModel model = new OfferBookChartViewModel(offerBook, empty, service, null, null);
model.activate();
assertEquals(7, model.maxPlacesForBuyPrice.intValue());
offerBookListItems.addAll(make(btcBuyItem.but(with(OfferBookListItemMaker.price, 94016475L))));
assertEquals(9, model.maxPlacesForBuyPrice.intValue()); // 9401.6475
offerBookListItems.addAll(make(btcBuyItem.but(with(OfferBookListItemMaker.price, 101016475L))));
assertEquals(10, model.maxPlacesForBuyPrice.intValue()); //10101.6475
}
@Test
public void testMaxCharactersForBuyVolumeWithNoOffers() {
OfferBook offerBook = mock(OfferBook.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookChartViewModel model = new OfferBookChartViewModel(offerBook, empty, null, null, null);
assertEquals(0, model.maxPlacesForBuyVolume.intValue());
}
@Test
public void testMaxCharactersForFiatBuyVolume() {
OfferBook offerBook = mock(OfferBook.class);
PriceFeedService service = mock(PriceFeedService.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
offerBookListItems.addAll(make(OfferBookListItemMaker.btcBuyItem));
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookChartViewModel model = new OfferBookChartViewModel(offerBook, empty, service, null, null);
model.activate();
assertEquals(1, model.maxPlacesForBuyVolume.intValue()); //0
offerBookListItems.addAll(make(btcBuyItem.but(with(OfferBookListItemMaker.amount, 100000000L))));
assertEquals(2, model.maxPlacesForBuyVolume.intValue()); //10
offerBookListItems.addAll(make(btcBuyItem.but(with(OfferBookListItemMaker.amount, 22128600000L))));
assertEquals(4, model.maxPlacesForBuyVolume.intValue()); //2213
}
@Test
public void testMaxCharactersForSellPriceWithNoOffers() {
OfferBook offerBook = mock(OfferBook.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookChartViewModel model = new OfferBookChartViewModel(offerBook, empty, null, null, null);
assertEquals(0, model.maxPlacesForSellPrice.intValue());
}
@Test
public void testMaxCharactersForSellPriceWithOfflinePriceFeedService() {
OfferBook offerBook = mock(OfferBook.class);
PriceFeedService priceFeedService = mock(PriceFeedService.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
final OfferBookListItem item = make(OfferBookListItemMaker.btcSellItem.but(with(OfferBookListItemMaker.useMarketBasedPrice, true)));
item.getOffer().setPriceFeedService(priceFeedService);
offerBookListItems.addAll(item);
when(priceFeedService.getMarketPrice(anyString())).thenReturn(null);
when(priceFeedService.updateCounterProperty()).thenReturn(new SimpleIntegerProperty());
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookChartViewModel model = new OfferBookChartViewModel(offerBook, empty, priceFeedService, null, null);
model.activate();
assertEquals(0, model.maxPlacesForSellPrice.intValue());
}
@Test
public void testMaxCharactersForFiatSellPrice() {
OfferBook offerBook = mock(OfferBook.class);
PriceFeedService service = mock(PriceFeedService.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
offerBookListItems.addAll(make(OfferBookListItemMaker.btcSellItem));
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookChartViewModel model = new OfferBookChartViewModel(offerBook, empty, service, null, null);
model.activate();
assertEquals(7, model.maxPlacesForSellPrice.intValue()); // 10.0000 default price
offerBookListItems.addAll(make(btcSellItem.but(with(OfferBookListItemMaker.price, 94016475L))));
assertEquals(9, model.maxPlacesForSellPrice.intValue()); // 9401.6475
offerBookListItems.addAll(make(btcSellItem.but(with(OfferBookListItemMaker.price, 101016475L))));
assertEquals(10, model.maxPlacesForSellPrice.intValue()); // 10101.6475
}
@Test
public void testMaxCharactersForSellVolumeWithNoOffers() {
OfferBook offerBook = mock(OfferBook.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookChartViewModel model = new OfferBookChartViewModel(offerBook, empty, null, null, null);
assertEquals(0, model.maxPlacesForSellVolume.intValue());
}
@Test
public void testMaxCharactersForFiatSellVolume() {
OfferBook offerBook = mock(OfferBook.class);
PriceFeedService service = mock(PriceFeedService.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
offerBookListItems.addAll(make(OfferBookListItemMaker.btcSellItem));
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookChartViewModel model = new OfferBookChartViewModel(offerBook, empty, service, null, null);
model.activate();
assertEquals(1, model.maxPlacesForSellVolume.intValue()); //0
offerBookListItems.addAll(make(btcSellItem.but(with(OfferBookListItemMaker.amount, 100000000L))));
assertEquals(2, model.maxPlacesForSellVolume.intValue()); //10
offerBookListItems.addAll(make(btcSellItem.but(with(OfferBookListItemMaker.amount, 22128600000L))));
assertEquals(4, model.maxPlacesForSellVolume.intValue()); //2213
}
}

View file

@ -0,0 +1,98 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.main.market.spread;
import bisq.desktop.main.offer.offerbook.OfferBook;
import bisq.desktop.main.offer.offerbook.OfferBookListItem;
import bisq.desktop.main.offer.offerbook.OfferBookListItemMaker;
import bisq.core.provider.price.PriceFeedService;
import bisq.core.util.coin.CoinFormatter;
import bisq.core.util.coin.ImmutableCoinFormatter;
import bisq.common.config.Config;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import org.junit.Test;
import static bisq.desktop.main.offer.offerbook.OfferBookListItemMaker.btcBuyItem;
import static bisq.desktop.main.offer.offerbook.OfferBookListItemMaker.btcSellItem;
import static bisq.desktop.main.offer.offerbook.OfferBookListItemMaker.id;
import static com.natpryce.makeiteasy.MakeItEasy.make;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class SpreadViewModelTest {
private final CoinFormatter coinFormatter = new ImmutableCoinFormatter(Config.baseCurrencyNetworkParameters().getMonetaryFormat());
@Test
public void testMaxCharactersForAmountWithNoOffers() {
OfferBook offerBook = mock(OfferBook.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
SpreadViewModel model = new SpreadViewModel(offerBook, null, coinFormatter);
assertEquals(0, model.maxPlacesForAmount.intValue());
}
@Test
public void testMaxCharactersForAmount() {
OfferBook offerBook = mock(OfferBook.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
offerBookListItems.addAll(make(btcBuyItem));
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
SpreadViewModel model = new SpreadViewModel(offerBook, null, coinFormatter);
model.activate();
assertEquals(6, model.maxPlacesForAmount.intValue()); // 0.001
offerBookListItems.addAll(make(btcBuyItem.but(with(OfferBookListItemMaker.amount, 1403000000L))));
assertEquals(7, model.maxPlacesForAmount.intValue()); //14.0300
}
@Test
public void testFilterSpreadItemsForUniqueOffers() {
OfferBook offerBook = mock(OfferBook.class);
PriceFeedService priceFeedService = mock(PriceFeedService.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
offerBookListItems.addAll(make(btcBuyItem));
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
SpreadViewModel model = new SpreadViewModel(offerBook, priceFeedService, coinFormatter);
model.activate();
assertEquals(1, model.spreadItems.get(0).numberOfOffers);
offerBookListItems.addAll(make(btcBuyItem.but(with(id, "2345"))),
make(btcBuyItem.but(with(id, "2345"))),
make(btcSellItem.but(with(id, "3456"))),
make(btcSellItem.but(with(id, "3456"))));
assertEquals(2, model.spreadItems.get(0).numberOfBuyOffers);
assertEquals(1, model.spreadItems.get(0).numberOfSellOffers);
assertEquals(3, model.spreadItems.get(0).numberOfOffers);
}
}

View file

@ -0,0 +1,249 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.main.market.trades;
import bisq.desktop.Navigation;
import bisq.desktop.main.market.trades.charts.CandleData;
import bisq.core.locale.FiatCurrency;
import bisq.core.monetary.Price;
import bisq.core.offer.OfferPayload;
import bisq.core.payment.payload.PaymentMethod;
import bisq.core.provider.price.PriceFeedService;
import bisq.core.trade.statistics.TradeStatistics3;
import bisq.core.trade.statistics.TradeStatisticsManager;
import bisq.core.user.Preferences;
import org.bitcoinj.core.Coin;
import org.bitcoinj.utils.Fiat;
import javafx.collections.FXCollections;
import javafx.collections.ObservableSet;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
public class TradesChartsViewModelTest {
TradesChartsViewModel model;
TradeStatisticsManager tradeStatisticsManager;
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
private File dir;
OfferPayload offer = new OfferPayload(null,
0,
null,
null,
null,
0,
0,
false,
0,
0,
"BTC",
"EUR",
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
0,
0,
0,
false,
0,
0,
0,
0,
false,
false,
0,
0,
false,
null,
null,
1
);
@Before
public void setup() throws IOException {
tradeStatisticsManager = mock(TradeStatisticsManager.class);
model = new TradesChartsViewModel(tradeStatisticsManager, mock(Preferences.class), mock(PriceFeedService.class),
mock(Navigation.class));
dir = File.createTempFile("temp_tests1", "");
//noinspection ResultOfMethodCallIgnored
dir.delete();
//noinspection ResultOfMethodCallIgnored
dir.mkdir();
}
@SuppressWarnings("ConstantConditions")
@Test
public void testGetCandleData() {
model.selectedTradeCurrencyProperty.setValue(new FiatCurrency("EUR"));
long low = Fiat.parseFiat("EUR", "500").value;
long open = Fiat.parseFiat("EUR", "520").value;
long close = Fiat.parseFiat("EUR", "580").value;
long high = Fiat.parseFiat("EUR", "600").value;
long average = Fiat.parseFiat("EUR", "550").value;
long median = Fiat.parseFiat("EUR", "550").value;
long amount = Coin.parseCoin("4").value;
long volume = Fiat.parseFiat("EUR", "2200").value;
boolean isBullish = true;
Set<TradeStatistics3> set = new HashSet<>();
final Date now = new Date();
set.add(new TradeStatistics3(offer.getCurrencyCode(),
Price.parse("EUR", "520").getValue(),
Coin.parseCoin("1").getValue(),
PaymentMethod.BLOCK_CHAINS_ID,
now.getTime(),
null,
null,
null,
null));
set.add(new TradeStatistics3(offer.getCurrencyCode(),
Price.parse("EUR", "500").getValue(),
Coin.parseCoin("1").getValue(),
PaymentMethod.BLOCK_CHAINS_ID,
now.getTime() + 100,
null,
null,
null,
null));
set.add(new TradeStatistics3(offer.getCurrencyCode(),
Price.parse("EUR", "600").getValue(),
Coin.parseCoin("1").getValue(),
PaymentMethod.BLOCK_CHAINS_ID,
now.getTime() + 200,
null,
null,
null,
null));
set.add(new TradeStatistics3(offer.getCurrencyCode(),
Price.parse("EUR", "580").getValue(),
Coin.parseCoin("1").getValue(),
PaymentMethod.BLOCK_CHAINS_ID,
now.getTime() + 300,
null,
null,
null,
null));
CandleData candleData = model.getCandleData(model.roundToTick(now, TradesChartsViewModel.TickUnit.DAY).getTime(), set, 0);
assertEquals(open, candleData.open);
assertEquals(close, candleData.close);
assertEquals(high, candleData.high);
assertEquals(low, candleData.low);
assertEquals(average, candleData.average);
assertEquals(median, candleData.median);
assertEquals(amount, candleData.accumulatedAmount);
assertEquals(volume, candleData.accumulatedVolume);
assertEquals(isBullish, candleData.isBullish);
}
// TODO JMOCKIT
@Ignore
@Test
public void testItemLists() throws ParseException {
// Helper class to add historic trades
class Trade {
Trade(String date, String size, String price, String cc) {
try {
this.date = dateFormat.parse(date);
} catch (ParseException p) {
this.date = new Date();
}
this.size = size;
this.price = price;
this.cc = cc;
}
Date date;
String size;
String price;
String cc;
}
// Trade EUR
model.selectedTradeCurrencyProperty.setValue(new FiatCurrency("EUR"));
ArrayList<Trade> trades = new ArrayList<>();
// Set predetermined time to use as "now" during test
/* new MockUp<System>() {
@Mock
long currentTimeMillis() {
return test_time.getTime();
}
};*/
// Two trades 10 seconds apart, different YEAR, MONTH, WEEK, DAY, HOUR, MINUTE_10
trades.add(new Trade("2017-12-31T23:59:52", "1", "100", "EUR"));
trades.add(new Trade("2018-01-01T00:00:02", "1", "110", "EUR"));
Set<TradeStatistics3> set = new HashSet<>();
trades.forEach(t ->
set.add(new TradeStatistics3(offer.getCurrencyCode(),
Price.parse(t.cc, t.price).getValue(),
Coin.parseCoin(t.size).getValue(),
PaymentMethod.BLOCK_CHAINS_ID,
t.date.getTime(),
null,
null,
null,
null))
);
ObservableSet<TradeStatistics3> tradeStats = FXCollections.observableSet(set);
// Run test for each tick type
for (TradesChartsViewModel.TickUnit tick : TradesChartsViewModel.TickUnit.values()) {
/* new Expectations() {{
tradeStatisticsManager.getObservableTradeStatisticsSet();
result = tradeStats;
}};*/
// Trigger chart update
model.setTickUnit(tick);
assertEquals(model.selectedTradeCurrencyProperty.get().getCode(), tradeStats.iterator().next().getCurrency());
assertEquals(2, model.priceItems.size());
assertEquals(2, model.volumeItems.size());
}
}
}

View file

@ -0,0 +1,125 @@
package bisq.desktop.main.offer.createoffer;
import bisq.core.btc.model.AddressEntry;
import bisq.core.btc.wallet.BtcWalletService;
import bisq.core.locale.CryptoCurrency;
import bisq.core.locale.FiatCurrency;
import bisq.core.locale.GlobalSettings;
import bisq.core.locale.Res;
import bisq.core.offer.CreateOfferService;
import bisq.core.offer.OfferUtil;
import bisq.core.payment.ClearXchangeAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.RevolutAccount;
import bisq.core.provider.fee.FeeService;
import bisq.core.provider.price.PriceFeedService;
import bisq.core.trade.statistics.TradeStatisticsManager;
import bisq.core.user.Preferences;
import bisq.core.user.User;
import org.bitcoinj.core.Coin;
import javafx.collections.FXCollections;
import java.util.HashSet;
import java.util.UUID;
import org.junit.Before;
import org.junit.Test;
import static bisq.core.offer.OfferPayload.Direction;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class CreateOfferDataModelTest {
private CreateOfferDataModel model;
private User user;
private Preferences preferences;
private OfferUtil offerUtil;
@Before
public void setUp() {
final CryptoCurrency btc = new CryptoCurrency("BTC", "bitcoin");
GlobalSettings.setDefaultTradeCurrency(btc);
Res.setup();
AddressEntry addressEntry = mock(AddressEntry.class);
BtcWalletService btcWalletService = mock(BtcWalletService.class);
PriceFeedService priceFeedService = mock(PriceFeedService.class);
FeeService feeService = mock(FeeService.class);
CreateOfferService createOfferService = mock(CreateOfferService.class);
preferences = mock(Preferences.class);
offerUtil = mock(OfferUtil.class);
user = mock(User.class);
var tradeStats = mock(TradeStatisticsManager.class);
when(btcWalletService.getOrCreateAddressEntry(anyString(), any())).thenReturn(addressEntry);
when(preferences.isUsePercentageBasedPrice()).thenReturn(true);
when(preferences.getBuyerSecurityDepositAsPercent(null)).thenReturn(0.01);
when(createOfferService.getRandomOfferId()).thenReturn(UUID.randomUUID().toString());
when(tradeStats.getObservableTradeStatisticsSet()).thenReturn(FXCollections.observableSet());
model = new CreateOfferDataModel(createOfferService,
null,
offerUtil,
btcWalletService,
null,
preferences,
user,
null,
priceFeedService,
null,
feeService,
null,
tradeStats,
null);
}
@Test
public void testUseTradeCurrencySetInOfferViewWhenInPaymentAccountAvailable() {
final HashSet<PaymentAccount> paymentAccounts = new HashSet<>();
final ClearXchangeAccount zelleAccount = new ClearXchangeAccount();
zelleAccount.setId("234");
zelleAccount.setAccountName("zelleAccount");
paymentAccounts.add(zelleAccount);
final RevolutAccount revolutAccount = new RevolutAccount();
revolutAccount.setId("123");
revolutAccount.setAccountName("revolutAccount");
revolutAccount.setSingleTradeCurrency(new FiatCurrency("EUR"));
revolutAccount.addCurrency(new FiatCurrency("USD"));
paymentAccounts.add(revolutAccount);
when(user.getPaymentAccounts()).thenReturn(paymentAccounts);
when(preferences.getSelectedPaymentAccountForCreateOffer()).thenReturn(revolutAccount);
when(offerUtil.getMakerFee(any())).thenReturn(Coin.ZERO);
model.initWithData(Direction.BUY, new FiatCurrency("USD"));
assertEquals("USD", model.getTradeCurrencyCode().get());
}
@Test
public void testUseTradeAccountThatMatchesTradeCurrencySetInOffer() {
final HashSet<PaymentAccount> paymentAccounts = new HashSet<>();
final ClearXchangeAccount zelleAccount = new ClearXchangeAccount();
zelleAccount.setId("234");
zelleAccount.setAccountName("zelleAccount");
paymentAccounts.add(zelleAccount);
final RevolutAccount revolutAccount = new RevolutAccount();
revolutAccount.setId("123");
revolutAccount.setAccountName("revolutAccount");
revolutAccount.setSingleTradeCurrency(new FiatCurrency("EUR"));
paymentAccounts.add(revolutAccount);
when(user.getPaymentAccounts()).thenReturn(paymentAccounts);
when(user.findFirstPaymentAccountWithCurrency(new FiatCurrency("USD"))).thenReturn(zelleAccount);
when(preferences.getSelectedPaymentAccountForCreateOffer()).thenReturn(revolutAccount);
when(offerUtil.getMakerFee(any())).thenReturn(Coin.ZERO);
model.initWithData(Direction.BUY, new FiatCurrency("USD"));
assertEquals("USD", model.getTradeCurrencyCode().get());
}
}

View file

@ -0,0 +1,243 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.main.offer.createoffer;
import bisq.desktop.util.validation.AltcoinValidator;
import bisq.desktop.util.validation.BtcValidator;
import bisq.desktop.util.validation.FiatPriceValidator;
import bisq.desktop.util.validation.SecurityDepositValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
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.CreateOfferService;
import bisq.core.offer.OfferUtil;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.payload.PaymentMethod;
import bisq.core.provider.fee.FeeService;
import bisq.core.provider.price.MarketPrice;
import bisq.core.provider.price.PriceFeedService;
import bisq.core.trade.statistics.TradeStatisticsManager;
import bisq.core.user.Preferences;
import bisq.core.user.User;
import bisq.core.util.coin.BsqFormatter;
import bisq.core.util.coin.CoinFormatter;
import bisq.core.util.coin.ImmutableCoinFormatter;
import bisq.core.util.validation.InputValidator;
import bisq.common.config.Config;
import org.bitcoinj.core.Coin;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import java.time.Instant;
import java.util.UUID;
import org.junit.Before;
import org.junit.Test;
import static bisq.core.offer.OfferPayload.Direction;
import static bisq.desktop.maker.PreferenceMakers.empty;
import static org.junit.Assert.assertEquals;
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;
public class CreateOfferViewModelTest {
private CreateOfferViewModel model;
private final CoinFormatter coinFormatter = new ImmutableCoinFormatter(
Config.baseCurrencyNetworkParameters().getMonetaryFormat());
@Before
public void setUp() {
final CryptoCurrency btc = new CryptoCurrency("BTC", "bitcoin");
GlobalSettings.setDefaultTradeCurrency(btc);
Res.setup();
final BtcValidator btcValidator = new BtcValidator(coinFormatter);
final AltcoinValidator altcoinValidator = new AltcoinValidator();
final FiatPriceValidator fiatPriceValidator = new FiatPriceValidator();
FeeService feeService = mock(FeeService.class);
AddressEntry addressEntry = mock(AddressEntry.class);
BtcWalletService btcWalletService = mock(BtcWalletService.class);
PriceFeedService priceFeedService = mock(PriceFeedService.class);
User 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);
CreateOfferService createOfferService = mock(CreateOfferService.class);
OfferUtil offerUtil = mock(OfferUtil.class);
var tradeStats = mock(TradeStatisticsManager.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(paymentAccount.getPaymentMethod()).thenReturn(mock(PaymentMethod.class));
when(user.getPaymentAccountsAsObservable()).thenReturn(FXCollections.observableSet());
when(securityDepositValidator.validate(any())).thenReturn(new InputValidator.ValidationResult(false));
when(accountAgeWitnessService.getMyTradeLimit(any(), any(), any())).thenReturn(100000000L);
when(preferences.getUserCountry()).thenReturn(new Country("ES", "Spain", null));
when(bsqFormatter.formatCoin(any())).thenReturn("0");
when(bsqWalletService.getAvailableConfirmedBalance()).thenReturn(Coin.ZERO);
when(createOfferService.getRandomOfferId()).thenReturn(UUID.randomUUID().toString());
when(tradeStats.getObservableTradeStatisticsSet()).thenReturn(FXCollections.observableSet());
CreateOfferDataModel dataModel = new CreateOfferDataModel(createOfferService,
null,
offerUtil,
btcWalletService,
bsqWalletService,
empty,
user,
null,
priceFeedService,
accountAgeWitnessService,
feeService,
coinFormatter,
tradeStats,
null);
dataModel.initWithData(Direction.BUY, new CryptoCurrency("BTC", "bitcoin"));
dataModel.activate();
model = new CreateOfferViewModel(dataModel,
null,
fiatPriceValidator,
altcoinValidator,
btcValidator,
null,
securityDepositValidator,
priceFeedService,
null,
null,
preferences,
coinFormatter,
bsqFormatter,
offerUtil);
model.activate();
}
@Test
public void testSyncMinAmountWithAmountUntilChanged() {
assertNull(model.amount.get());
assertNull(model.minAmount.get());
model.amount.set("0.0");
assertEquals("0.0", model.amount.get());
assertNull(model.minAmount.get());
model.amount.set("0.03");
assertEquals("0.03", model.amount.get());
assertEquals("0.03", model.minAmount.get());
model.amount.set("0.0312");
assertEquals("0.0312", model.amount.get());
assertEquals("0.0312", model.minAmount.get());
model.minAmount.set("0.01");
model.onFocusOutMinAmountTextField(true, false);
assertEquals("0.01", model.minAmount.get());
model.amount.set("0.0301");
assertEquals("0.0301", model.amount.get());
assertEquals("0.01", model.minAmount.get());
}
@Test
public void testSyncMinAmountWithAmountWhenZeroCoinIsSet() {
model.amount.set("0.03");
assertEquals("0.03", model.amount.get());
assertEquals("0.03", model.minAmount.get());
model.minAmount.set("0.00");
model.onFocusOutMinAmountTextField(true, false);
model.amount.set("0.04");
assertEquals("0.04", model.amount.get());
assertEquals("0.04", model.minAmount.get());
}
@Test
public void testSyncMinAmountWithAmountWhenSameValueIsSet() {
model.amount.set("0.03");
assertEquals("0.03", model.amount.get());
assertEquals("0.03", model.minAmount.get());
model.minAmount.set("0.03");
model.onFocusOutMinAmountTextField(true, false);
model.amount.set("0.04");
assertEquals("0.04", model.amount.get());
assertEquals("0.04", model.minAmount.get());
}
@Test
public void testSyncMinAmountWithAmountWhenHigherMinAmountValueIsSet() {
model.amount.set("0.03");
assertEquals("0.03", model.amount.get());
assertEquals("0.03", model.minAmount.get());
model.minAmount.set("0.05");
model.onFocusOutMinAmountTextField(true, false);
assertEquals("0.05", model.amount.get());
assertEquals("0.05", model.minAmount.get());
}
@Test
public void testSyncPriceMarginWithVolumeAndFixedPrice() {
model.amount.set("0.01");
model.onFocusOutPriceAsPercentageTextField(true, false); //leave focus without changing
assertEquals("0.00", model.marketPriceMargin.get());
assertEquals("0.00000078", model.volume.get());
assertEquals("12684.04500000", model.price.get());
}
}

View file

@ -0,0 +1,69 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.main.offer.offerbook;
import bisq.desktop.maker.OfferMaker;
import bisq.core.offer.OfferPayload;
import com.natpryce.makeiteasy.Instantiator;
import com.natpryce.makeiteasy.MakeItEasy;
import com.natpryce.makeiteasy.Maker;
import com.natpryce.makeiteasy.Property;
import static bisq.desktop.maker.OfferMaker.btcUsdOffer;
import static com.natpryce.makeiteasy.MakeItEasy.a;
import static com.natpryce.makeiteasy.MakeItEasy.make;
import static com.natpryce.makeiteasy.MakeItEasy.with;
public class OfferBookListItemMaker {
public static final Property<OfferBookListItem, String> id = new Property<>();
public static final Property<OfferBookListItem, Long> price = new Property<>();
public static final Property<OfferBookListItem, Long> amount = new Property<>();
public static final Property<OfferBookListItem, Long> minAmount = new Property<>();
public static final Property<OfferBookListItem, OfferPayload.Direction> direction = new Property<>();
public static final Property<OfferBookListItem, Boolean> useMarketBasedPrice = new Property<>();
public static final Property<OfferBookListItem, Double> marketPriceMargin = new Property<>();
public static final Property<OfferBookListItem, String> baseCurrencyCode = new Property<>();
public static final Property<OfferBookListItem, String> counterCurrencyCode = new Property<>();
public static final Instantiator<OfferBookListItem> OfferBookListItem = lookup ->
new OfferBookListItem(make(btcUsdOffer.but(
MakeItEasy.with(OfferMaker.price, lookup.valueOf(price, 100000L)),
with(OfferMaker.amount, lookup.valueOf(amount, 100000L)),
with(OfferMaker.minAmount, lookup.valueOf(amount, 100000L)),
with(OfferMaker.direction, lookup.valueOf(direction, OfferPayload.Direction.BUY)),
with(OfferMaker.useMarketBasedPrice, lookup.valueOf(useMarketBasedPrice, false)),
with(OfferMaker.marketPriceMargin, lookup.valueOf(marketPriceMargin, 0.0)),
with(OfferMaker.baseCurrencyCode, lookup.valueOf(baseCurrencyCode, "BTC")),
with(OfferMaker.counterCurrencyCode, lookup.valueOf(counterCurrencyCode, "USD")),
with(OfferMaker.id, lookup.valueOf(id, "1234"))
)));
public static final Instantiator<OfferBookListItem> OfferBookListItemWithRange = lookup ->
new OfferBookListItem(make(btcUsdOffer.but(
MakeItEasy.with(OfferMaker.price, lookup.valueOf(price, 100000L)),
with(OfferMaker.minAmount, lookup.valueOf(minAmount, 100000L)),
with(OfferMaker.amount, lookup.valueOf(amount, 200000L)))));
public static final Maker<OfferBookListItem> btcBuyItem = a(OfferBookListItem);
public static final Maker<OfferBookListItem> btcSellItem = a(OfferBookListItem, with(direction, OfferPayload.Direction.SELL));
public static final Maker<OfferBookListItem> btcItemWithRange = a(OfferBookListItemWithRange);
}

View file

@ -0,0 +1,626 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.main.offer.offerbook;
import bisq.desktop.main.PriceUtil;
import bisq.core.locale.Country;
import bisq.core.locale.CryptoCurrency;
import bisq.core.locale.FiatCurrency;
import bisq.core.locale.GlobalSettings;
import bisq.core.locale.Res;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OpenOfferManager;
import bisq.core.payment.AliPayAccount;
import bisq.core.payment.CountryBasedPaymentAccount;
import bisq.core.payment.CryptoCurrencyAccount;
import bisq.core.payment.NationalBankAccount;
import bisq.core.payment.PaymentAccount;
import bisq.core.payment.PaymentAccountUtil;
import bisq.core.payment.SameBankAccount;
import bisq.core.payment.SepaAccount;
import bisq.core.payment.SpecificBanksAccount;
import bisq.core.payment.payload.NationalBankAccountPayload;
import bisq.core.payment.payload.PaymentMethod;
import bisq.core.payment.payload.SameBankAccountPayload;
import bisq.core.payment.payload.SepaAccountPayload;
import bisq.core.payment.payload.SpecificBanksAccountPayload;
import bisq.core.provider.price.MarketPrice;
import bisq.core.provider.price.PriceFeedService;
import bisq.core.trade.statistics.TradeStatisticsManager;
import bisq.core.util.coin.BsqFormatter;
import bisq.core.util.coin.CoinFormatter;
import bisq.core.util.coin.ImmutableCoinFormatter;
import bisq.common.config.Config;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.natpryce.makeiteasy.Maker;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import static bisq.desktop.main.offer.offerbook.OfferBookListItemMaker.*;
import static bisq.desktop.maker.PreferenceMakers.empty;
import static bisq.desktop.maker.TradeCurrencyMakers.usd;
import static com.natpryce.makeiteasy.MakeItEasy.make;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class OfferBookViewModelTest {
private final CoinFormatter coinFormatter = new ImmutableCoinFormatter(Config.baseCurrencyNetworkParameters().getMonetaryFormat());
private static final Logger log = LoggerFactory.getLogger(OfferBookViewModelTest.class);
@Before
public void setUp() {
GlobalSettings.setDefaultTradeCurrency(usd);
Res.setBaseCurrencyCode(usd.getCode());
Res.setBaseCurrencyName(usd.getName());
}
private PriceUtil getPriceUtil() {
PriceFeedService priceFeedService = mock(PriceFeedService.class);
TradeStatisticsManager tradeStatisticsManager = mock(TradeStatisticsManager.class);
when(tradeStatisticsManager.getObservableTradeStatisticsSet()).thenReturn(FXCollections.observableSet());
return new PriceUtil(priceFeedService, tradeStatisticsManager, empty);
}
@Ignore("PaymentAccountPayload needs to be set (has been changed with PB changes)")
public void testIsAnyPaymentAccountValidForOffer() {
Collection<PaymentAccount> paymentAccounts;
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getSepaAccount("EUR", "DE", "1212324",
new ArrayList<>(Arrays.asList("AT", "DE")))));
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getSEPAPaymentMethod("EUR", "AT", new ArrayList<>(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts));
// empty paymentAccounts
paymentAccounts = new ArrayList<>();
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(getSEPAPaymentMethod("EUR", "AT",
new ArrayList<>(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts));
// simple cases: same payment methods
// offer: alipay paymentAccount: alipay - same country, same currency
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getAliPayAccount("CNY")));
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getAliPayPaymentMethod("EUR"), paymentAccounts));
// offer: ether paymentAccount: ether - same country, same currency
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getCryptoAccount("ETH")));
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getBlockChainsPaymentMethod("ETH"), paymentAccounts));
// offer: sepa paymentAccount: sepa - same country, same currency
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getSepaAccount("EUR", "AT", "1212324",
new ArrayList<>(Arrays.asList("AT", "DE")))));
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getSEPAPaymentMethod("EUR", "AT", new ArrayList<>(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts));
// offer: nationalBank paymentAccount: nationalBank - same country, same currency
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getNationalBankAccount("EUR", "AT", "PSK")));
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// offer: SameBank paymentAccount: SameBank - same country, same currency
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getSameBankAccount("EUR", "AT", "PSK")));
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getSameBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// offer: sepa paymentAccount: sepa - diff. country, same currency
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getSepaAccount("EUR", "DE", "1212324", new ArrayList<>(Arrays.asList("AT", "DE")))));
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getSEPAPaymentMethod("EUR", "AT", new ArrayList<>(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts));
//////
// offer: sepa paymentAccount: sepa - same country, same currency
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getSepaAccount("EUR", "AT", "1212324", new ArrayList<>(Arrays.asList("AT", "DE")))));
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getSEPAPaymentMethod("EUR", "AT", new ArrayList<>(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts));
// offer: sepa paymentAccount: nationalBank - same country, same currency
// wrong method
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getNationalBankAccount("EUR", "AT", "PSK")));
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getSEPAPaymentMethod("EUR", "AT", new ArrayList<>(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts));
// wrong currency
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getNationalBankAccount("USD", "US", "XXX")));
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// wrong country
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getNationalBankAccount("EUR", "FR", "PSK")));
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// sepa wrong country
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getNationalBankAccount("EUR", "CH", "PSK")));
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getSEPAPaymentMethod("EUR", "AT", new ArrayList<>(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts));
// sepa wrong currency
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getNationalBankAccount("CHF", "DE", "PSK")));
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getSEPAPaymentMethod("EUR", "AT", new ArrayList<>(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts));
// same bank
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getSameBankAccount("EUR", "AT", "PSK")));
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// not same bank
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getSameBankAccount("EUR", "AT", "Raika")));
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// same bank, wrong country
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getSameBankAccount("EUR", "DE", "PSK")));
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// same bank, wrong currency
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getSameBankAccount("USD", "AT", "PSK")));
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// spec. bank
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getSpecificBanksAccount("EUR", "AT", "PSK",
new ArrayList<>(Arrays.asList("PSK", "Raika")))));
assertTrue(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// spec. bank, missing bank
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getSpecificBanksAccount("EUR", "AT", "PSK",
new ArrayList<>(FXCollections.singletonObservableList("Raika")))));
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// spec. bank, wrong country
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getSpecificBanksAccount("EUR", "FR", "PSK",
new ArrayList<>(Arrays.asList("PSK", "Raika")))));
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
// spec. bank, wrong currency
paymentAccounts = new ArrayList<>(FXCollections.singletonObservableList(getSpecificBanksAccount("USD", "AT", "PSK",
new ArrayList<>(Arrays.asList("PSK", "Raika")))));
assertFalse(PaymentAccountUtil.isAnyPaymentAccountValidForOffer(
getNationalBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts));
//TODO add more tests
}
@Test
public void testMaxCharactersForAmountWithNoOffers() {
OfferBook offerBook = mock(OfferBook.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookViewModel model = new OfferBookViewModel(null, null, offerBook, empty, null, null, null,
null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter());
assertEquals(0, model.maxPlacesForAmount.intValue());
}
@Test
public void testMaxCharactersForAmount() {
OfferBook offerBook = mock(OfferBook.class);
OpenOfferManager openOfferManager = mock(OpenOfferManager.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
offerBookListItems.addAll(make(OfferBookListItemMaker.btcBuyItem));
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookViewModel model = new OfferBookViewModel(null, openOfferManager, offerBook, empty, null, null, null,
null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter());
model.activate();
assertEquals(6, model.maxPlacesForAmount.intValue());
offerBookListItems.addAll(make(btcBuyItem.but(with(amount, 2000000000L))));
assertEquals(7, model.maxPlacesForAmount.intValue());
}
@Test
public void testMaxCharactersForAmountRange() {
OfferBook offerBook = mock(OfferBook.class);
OpenOfferManager openOfferManager = mock(OpenOfferManager.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
offerBookListItems.addAll(make(OfferBookListItemMaker.btcItemWithRange));
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookViewModel model = new OfferBookViewModel(null, openOfferManager, offerBook, empty, null, null, null,
null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter());
model.activate();
assertEquals(15, model.maxPlacesForAmount.intValue());
offerBookListItems.addAll(make(btcItemWithRange.but(with(amount, 2000000000L))));
assertEquals(16, model.maxPlacesForAmount.intValue());
offerBookListItems.addAll(make(btcItemWithRange.but(with(minAmount, 30000000000L),
with(amount, 30000000000L))));
assertEquals(19, model.maxPlacesForAmount.intValue());
}
@Test
public void testMaxCharactersForVolumeWithNoOffers() {
OfferBook offerBook = mock(OfferBook.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookViewModel model = new OfferBookViewModel(null, null, offerBook, empty, null, null, null,
null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter());
assertEquals(0, model.maxPlacesForVolume.intValue());
}
@Test
public void testMaxCharactersForVolume() {
OfferBook offerBook = mock(OfferBook.class);
OpenOfferManager openOfferManager = mock(OpenOfferManager.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
offerBookListItems.addAll(make(OfferBookListItemMaker.btcBuyItem));
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookViewModel model = new OfferBookViewModel(null, openOfferManager, offerBook, empty, null, null, null,
null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter());
model.activate();
assertEquals(5, model.maxPlacesForVolume.intValue());
offerBookListItems.addAll(make(btcBuyItem.but(with(amount, 2000000000L))));
assertEquals(7, model.maxPlacesForVolume.intValue());
}
@Test
public void testMaxCharactersForVolumeRange() {
OfferBook offerBook = mock(OfferBook.class);
OpenOfferManager openOfferManager = mock(OpenOfferManager.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
offerBookListItems.addAll(make(OfferBookListItemMaker.btcItemWithRange));
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookViewModel model = new OfferBookViewModel(null, openOfferManager, offerBook, empty, null, null, null,
null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter());
model.activate();
assertEquals(9, model.maxPlacesForVolume.intValue());
offerBookListItems.addAll(make(btcItemWithRange.but(with(amount, 2000000000L))));
assertEquals(11, model.maxPlacesForVolume.intValue());
offerBookListItems.addAll(make(btcItemWithRange.but(with(minAmount, 30000000000L),
with(amount, 30000000000L))));
assertEquals(19, model.maxPlacesForVolume.intValue());
}
@Test
public void testMaxCharactersForPriceWithNoOffers() {
OfferBook offerBook = mock(OfferBook.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookViewModel model = new OfferBookViewModel(null, null, offerBook, empty, null, null, null,
null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter());
assertEquals(0, model.maxPlacesForPrice.intValue());
}
@Test
public void testMaxCharactersForPrice() {
OfferBook offerBook = mock(OfferBook.class);
OpenOfferManager openOfferManager = mock(OpenOfferManager.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
offerBookListItems.addAll(make(OfferBookListItemMaker.btcBuyItem));
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookViewModel model = new OfferBookViewModel(null, openOfferManager, offerBook, empty, null, null, null,
null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter());
model.activate();
assertEquals(7, model.maxPlacesForPrice.intValue());
offerBookListItems.addAll(make(btcBuyItem.but(with(price, 149558240L)))); //14955.8240
assertEquals(10, model.maxPlacesForPrice.intValue());
offerBookListItems.addAll(make(btcBuyItem.but(with(price, 14955824L)))); //1495.58240
assertEquals(10, model.maxPlacesForPrice.intValue());
}
@Test
public void testMaxCharactersForPriceDistanceWithNoOffers() {
OfferBook offerBook = mock(OfferBook.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
final OfferBookViewModel model = new OfferBookViewModel(null, null, offerBook, empty, null, null, null,
null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter());
assertEquals(0, model.maxPlacesForMarketPriceMargin.intValue());
}
@Test
public void testMaxCharactersForPriceDistance() {
OfferBook offerBook = mock(OfferBook.class);
OpenOfferManager openOfferManager = mock(OpenOfferManager.class);
PriceFeedService priceFeedService = mock(PriceFeedService.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
final Maker<OfferBookListItem> item = btcBuyItem.but(with(useMarketBasedPrice, true));
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
when(priceFeedService.getMarketPrice(anyString())).thenReturn(null);
when(priceFeedService.updateCounterProperty()).thenReturn(new SimpleIntegerProperty());
final OfferBookListItem item1 = make(item);
item1.getOffer().setPriceFeedService(priceFeedService);
final OfferBookListItem item2 = make(item.but(with(marketPriceMargin, 0.0197)));
item2.getOffer().setPriceFeedService(priceFeedService);
final OfferBookListItem item3 = make(item.but(with(marketPriceMargin, 0.1)));
item3.getOffer().setPriceFeedService(priceFeedService);
final OfferBookListItem item4 = make(item.but(with(marketPriceMargin, -0.1)));
item4.getOffer().setPriceFeedService(priceFeedService);
offerBookListItems.addAll(item1, item2);
final OfferBookViewModel model = new OfferBookViewModel(null, openOfferManager, offerBook, empty, null, null, priceFeedService,
null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter());
model.activate();
assertEquals(8, model.maxPlacesForMarketPriceMargin.intValue()); //" (1.97%)"
offerBookListItems.addAll(item3);
assertEquals(9, model.maxPlacesForMarketPriceMargin.intValue()); //" (10.00%)"
offerBookListItems.addAll(item4);
assertEquals(10, model.maxPlacesForMarketPriceMargin.intValue()); //" (-10.00%)"
}
@Test
public void testGetPrice() {
OfferBook offerBook = mock(OfferBook.class);
OpenOfferManager openOfferManager = mock(OpenOfferManager.class);
PriceFeedService priceFeedService = mock(PriceFeedService.class);
final ObservableList<OfferBookListItem> offerBookListItems = FXCollections.observableArrayList();
when(offerBook.getOfferBookListItems()).thenReturn(offerBookListItems);
when(priceFeedService.getMarketPrice(anyString())).thenReturn(new MarketPrice("USD", 12684.0450, Instant.now().getEpochSecond(), true));
final OfferBookViewModel model = new OfferBookViewModel(null, openOfferManager, offerBook, empty, null, null, null,
null, null, null, getPriceUtil(), null, coinFormatter, new BsqFormatter());
final OfferBookListItem item = make(btcBuyItem.but(
with(useMarketBasedPrice, true),
with(marketPriceMargin, -0.12)));
final OfferBookListItem lowItem = make(btcBuyItem.but(
with(useMarketBasedPrice, true),
with(marketPriceMargin, 0.01)));
final OfferBookListItem fixedItem = make(btcBuyItem);
item.getOffer().setPriceFeedService(priceFeedService);
lowItem.getOffer().setPriceFeedService(priceFeedService);
offerBookListItems.addAll(lowItem, fixedItem);
model.activate();
assertEquals("12557.2046", model.getPrice(lowItem));
assertEquals("(1.00%)", model.getPriceAsPercentage(lowItem));
assertEquals("10.0000", model.getPrice(fixedItem));
offerBookListItems.addAll(item);
assertEquals("14206.1304", model.getPrice(item));
assertEquals("(-12.00%)", model.getPriceAsPercentage(item));
assertEquals("12557.2046", model.getPrice(lowItem));
assertEquals("(1.00%)", model.getPriceAsPercentage(lowItem));
}
private PaymentAccount getAliPayAccount(String currencyCode) {
PaymentAccount paymentAccount = new AliPayAccount();
paymentAccount.setSelectedTradeCurrency(new FiatCurrency(currencyCode));
return paymentAccount;
}
private PaymentAccount getCryptoAccount(String currencyCode) {
PaymentAccount paymentAccount = new CryptoCurrencyAccount();
paymentAccount.addCurrency(new CryptoCurrency(currencyCode, null));
return paymentAccount;
}
private PaymentAccount getSepaAccount(String currencyCode,
String countryCode,
String bic,
ArrayList<String> countryCodes) {
CountryBasedPaymentAccount paymentAccount = new SepaAccount();
paymentAccount.setSingleTradeCurrency(new FiatCurrency(currencyCode));
paymentAccount.setCountry(new Country(countryCode, null, null));
((SepaAccountPayload) paymentAccount.getPaymentAccountPayload()).setBic(bic);
countryCodes.forEach(((SepaAccountPayload) paymentAccount.getPaymentAccountPayload())::addAcceptedCountry);
return paymentAccount;
}
private PaymentAccount getNationalBankAccount(String currencyCode, String countryCode, String bankId) {
CountryBasedPaymentAccount paymentAccount = new NationalBankAccount();
paymentAccount.setSingleTradeCurrency(new FiatCurrency(currencyCode));
paymentAccount.setCountry(new Country(countryCode, null, null));
((NationalBankAccountPayload) paymentAccount.getPaymentAccountPayload()).setBankId(bankId);
return paymentAccount;
}
private PaymentAccount getSameBankAccount(String currencyCode, String countryCode, String bankId) {
SameBankAccount paymentAccount = new SameBankAccount();
paymentAccount.setSingleTradeCurrency(new FiatCurrency(currencyCode));
paymentAccount.setCountry(new Country(countryCode, null, null));
((SameBankAccountPayload) paymentAccount.getPaymentAccountPayload()).setBankId(bankId);
return paymentAccount;
}
private PaymentAccount getSpecificBanksAccount(String currencyCode,
String countryCode,
String bankId,
ArrayList<String> bankIds) {
SpecificBanksAccount paymentAccount = new SpecificBanksAccount();
paymentAccount.setSingleTradeCurrency(new FiatCurrency(currencyCode));
paymentAccount.setCountry(new Country(countryCode, null, null));
((SpecificBanksAccountPayload) paymentAccount.getPaymentAccountPayload()).setBankId(bankId);
bankIds.forEach(((SpecificBanksAccountPayload) paymentAccount.getPaymentAccountPayload())::addAcceptedBank);
return paymentAccount;
}
private Offer getBlockChainsPaymentMethod(String currencyCode) {
return getOffer(currencyCode,
PaymentMethod.BLOCK_CHAINS_ID,
null,
null,
null,
null);
}
private Offer getAliPayPaymentMethod(String currencyCode) {
return getOffer(currencyCode,
PaymentMethod.ALI_PAY_ID,
null,
null,
null,
null);
}
private Offer getSEPAPaymentMethod(String currencyCode,
String countryCode,
ArrayList<String> countryCodes,
String bankId) {
return getPaymentMethod(currencyCode,
PaymentMethod.SEPA_ID,
countryCode,
countryCodes,
bankId,
null);
}
private Offer getNationalBankPaymentMethod(String currencyCode, String countryCode, String bankId) {
return getPaymentMethod(currencyCode,
PaymentMethod.NATIONAL_BANK_ID,
countryCode,
new ArrayList<>(FXCollections.singletonObservableList(countryCode)),
bankId,
null);
}
private Offer getSameBankPaymentMethod(String currencyCode, String countryCode, String bankId) {
return getPaymentMethod(currencyCode,
PaymentMethod.SAME_BANK_ID,
countryCode,
new ArrayList<>(FXCollections.singletonObservableList(countryCode)),
bankId,
new ArrayList<>(FXCollections.singletonObservableList(bankId)));
}
private Offer getSpecificBanksPaymentMethod(String currencyCode,
String countryCode,
String bankId,
ArrayList<String> bankIds) {
return getPaymentMethod(currencyCode,
PaymentMethod.SPECIFIC_BANKS_ID,
countryCode,
new ArrayList<>(FXCollections.singletonObservableList(countryCode)),
bankId,
bankIds);
}
private Offer getPaymentMethod(String currencyCode,
String paymentMethodId,
String countryCode,
ArrayList<String> countryCodes,
String bankId,
ArrayList<String> bankIds) {
return getOffer(currencyCode,
paymentMethodId,
countryCode,
countryCodes,
bankId,
bankIds);
}
private Offer getOffer(String tradeCurrencyCode,
String paymentMethodId,
String countryCode,
ArrayList<String> acceptedCountryCodes,
String bankId,
ArrayList<String> acceptedBanks) {
return new Offer(new OfferPayload(null,
0,
null,
null,
null,
0,
0,
false,
0,
0,
"BTC",
tradeCurrencyCode,
null,
null,
paymentMethodId,
null,
null,
countryCode,
acceptedCountryCodes,
bankId,
acceptedBanks,
null,
0,
0,
0,
false,
0,
0,
0,
0,
false,
false,
0,
0,
false,
null,
null,
1));
}
}

View file

@ -0,0 +1,47 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.main.overlays;
import org.junit.Test;
public class OverlayTest {
@Test
public void typeSafeCreation() {
new A();
new C();
new D<>();
}
@Test(expected = RuntimeException.class)
public void typeUnsafeCreation() {
new B();
}
private static class A extends Overlay<A> {
}
private static class B extends Overlay<A> {
}
private static class C extends TabbedOverlay<C> {
}
private static class D<T> extends Overlay<D<T>> {
}
}

View file

@ -0,0 +1,89 @@
/*
* This file is part of Bisq.
*
* bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.main.overlays.windows.downloadupdate;
import bisq.desktop.main.overlays.windows.downloadupdate.BisqInstaller.FileDescriptor;
import com.google.common.collect.Lists;
import java.net.URL;
import java.io.File;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
@Slf4j
public class BisqInstallerTest {
@Test
public void call() throws Exception {
}
@Test
public void verifySignature() throws Exception {
URL url = this.getClass().getResource("/downloadUpdate/test.txt");
File dataFile = new File(url.toURI().getPath());
url = this.getClass().getResource("/downloadUpdate/test.txt.asc");
File sigFile = new File(url.toURI().getPath());
url = this.getClass().getResource("/downloadUpdate/F379A1C6.asc");
File pubKeyFile = new File(url.toURI().getPath());
assertEquals(BisqInstaller.VerifyStatusEnum.OK, BisqInstaller.verifySignature(pubKeyFile, sigFile, dataFile));
url = this.getClass().getResource("/downloadUpdate/test_bad.txt");
dataFile = new File(url.toURI().getPath());
url = this.getClass().getResource("/downloadUpdate/test_bad.txt.asc");
sigFile = new File(url.toURI().getPath());
url = this.getClass().getResource("/downloadUpdate/F379A1C6.asc");
pubKeyFile = new File(url.toURI().getPath());
BisqInstaller.verifySignature(pubKeyFile, sigFile, dataFile);
assertEquals(BisqInstaller.VerifyStatusEnum.FAIL, BisqInstaller.verifySignature(pubKeyFile, sigFile, dataFile));
}
@Test
public void getFileName() throws Exception {
}
@Test
public void getDownloadType() throws Exception {
}
@Test
public void getIndex() throws Exception {
}
@Test
public void getSigFileDescriptors() throws Exception {
BisqInstaller bisqInstaller = new BisqInstaller();
FileDescriptor installerFileDescriptor = FileDescriptor.builder().fileName("filename.txt").id("filename").loadUrl("url://filename.txt").build();
FileDescriptor key1 = FileDescriptor.builder().fileName("key1").id("key1").loadUrl("").build();
FileDescriptor key2 = FileDescriptor.builder().fileName("key2").id("key2").loadUrl("").build();
List<FileDescriptor> sigFileDescriptors = bisqInstaller.getSigFileDescriptors(installerFileDescriptor, Lists.newArrayList(key1));
assertEquals(1, sigFileDescriptors.size());
sigFileDescriptors = bisqInstaller.getSigFileDescriptors(installerFileDescriptor, Lists.newArrayList(key1, key2));
assertEquals(2, sigFileDescriptors.size());
log.info("test");
}
}

View file

@ -0,0 +1,27 @@
/*
* This file is part of Bisq.
*
* bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.main.overlays.windows.downloadupdate;
import org.junit.Test;
public class VerifyTaskTest {
@Test
public void call() throws Exception {
}
}

View file

@ -0,0 +1,134 @@
package bisq.desktop.main.portfolio.editoffer;
import bisq.desktop.util.validation.SecurityDepositValidator;
import bisq.core.account.witness.AccountAgeWitnessService;
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.CreateOfferService;
import bisq.core.offer.OfferPayload;
import bisq.core.offer.OfferUtil;
import bisq.core.offer.OpenOffer;
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.trade.statistics.TradeStatisticsManager;
import bisq.core.user.Preferences;
import bisq.core.user.User;
import bisq.core.util.coin.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 java.util.UUID;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
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;
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();
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);
CreateOfferService createOfferService = mock(CreateOfferService.class);
OfferUtil offerUtil = mock(OfferUtil.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(), any())).thenReturn(100000000L);
when(preferences.getUserCountry()).thenReturn(new Country("US", "United States", null));
when(bsqFormatter.formatCoin(any())).thenReturn("0");
when(bsqWalletService.getAvailableConfirmedBalance()).thenReturn(Coin.ZERO);
when(createOfferService.getRandomOfferId()).thenReturn(UUID.randomUUID().toString());
model = new EditOfferDataModel(createOfferService,
null,
offerUtil,
btcWalletService,
bsqWalletService,
empty,
user,
null,
priceFeedService,
accountAgeWitnessService,
feeService,
null,
null,
mock(TradeStatisticsManager.class),
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)));
assertNull(model.getPreselectedPaymentAccount());
}
@Test
public void testInitializeEditOfferWithRemovedAsset() {
exception.expect(IllegalArgumentException.class);
model.initWithData(OfferPayload.Direction.BUY, null);
}
}

View file

@ -0,0 +1,144 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.main.settings.preferences;
import bisq.desktop.maker.PreferenceMakers;
import bisq.core.support.dispute.mediation.mediator.Mediator;
import bisq.core.support.dispute.mediation.mediator.MediatorManager;
import bisq.core.support.dispute.refund.refundagent.RefundAgent;
import bisq.core.support.dispute.refund.refundagent.RefundAgentManager;
import bisq.core.user.Preferences;
import bisq.network.p2p.NodeAddress;
import javafx.collections.FXCollections;
import javafx.collections.ObservableMap;
import java.util.ArrayList;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class PreferencesViewModelTest {
@Test
public void getArbitrationLanguages() {
RefundAgentManager refundAgentManager = mock(RefundAgentManager.class);
final ObservableMap<NodeAddress, RefundAgent> refundAgents = FXCollections.observableHashMap();
ArrayList<String> languagesOne = new ArrayList<>() {{
add("en");
add("de");
}};
ArrayList<String> languagesTwo = new ArrayList<>() {{
add("en");
add("es");
}};
RefundAgent one = new RefundAgent(new NodeAddress("refundAgent:1"), null, languagesOne, 0L,
null, null, null, null, null);
RefundAgent two = new RefundAgent(new NodeAddress("refundAgent:2"), null, languagesTwo, 0L,
null, null, null, null, null);
refundAgents.put(one.getNodeAddress(), one);
refundAgents.put(two.getNodeAddress(), two);
Preferences preferences = PreferenceMakers.empty;
when(refundAgentManager.getObservableMap()).thenReturn(refundAgents);
PreferencesViewModel model = new PreferencesViewModel(preferences, refundAgentManager, null);
assertEquals("English, Deutsch, español", model.getArbitrationLanguages());
}
@Test
public void getMediationLanguages() {
MediatorManager mediationManager = mock(MediatorManager.class);
final ObservableMap<NodeAddress, Mediator> mnediators = FXCollections.observableHashMap();
ArrayList<String> languagesOne = new ArrayList<>() {{
add("en");
add("de");
}};
ArrayList<String> languagesTwo = new ArrayList<>() {{
add("en");
add("es");
}};
Mediator one = new Mediator(new NodeAddress("refundAgent:1"), null, languagesOne, 0L,
null, null, null, null, null);
Mediator two = new Mediator(new NodeAddress("refundAgent:2"), null, languagesTwo, 0L,
null, null, null, null, null);
mnediators.put(one.getNodeAddress(), one);
mnediators.put(two.getNodeAddress(), two);
Preferences preferences = PreferenceMakers.empty;
when(mediationManager.getObservableMap()).thenReturn(mnediators);
PreferencesViewModel model = new PreferencesViewModel(preferences, null, mediationManager);
assertEquals("English, Deutsch, español", model.getMediationLanguages());
}
@Test
public void needsSupportLanguageWarning_forNotSupportedLanguageInArbitration() {
MediatorManager mediationManager = mock(MediatorManager.class);
RefundAgentManager refundAgentManager = mock(RefundAgentManager.class);
Preferences preferences = PreferenceMakers.empty;
when(refundAgentManager.isAgentAvailableForLanguage(preferences.getUserLanguage())).thenReturn(false);
PreferencesViewModel model = new PreferencesViewModel(preferences, refundAgentManager, mediationManager);
assertTrue(model.needsSupportLanguageWarning());
}
@Test
public void needsSupportLanguageWarning_forNotSupportedLanguageInMediation() {
MediatorManager mediationManager = mock(MediatorManager.class);
RefundAgentManager refundAgentManager = mock(RefundAgentManager.class);
Preferences preferences = PreferenceMakers.empty;
when(refundAgentManager.isAgentAvailableForLanguage(preferences.getUserLanguage())).thenReturn(true);
when(mediationManager.isAgentAvailableForLanguage(preferences.getUserLanguage())).thenReturn(false);
PreferencesViewModel model = new PreferencesViewModel(preferences, refundAgentManager, mediationManager);
assertTrue(model.needsSupportLanguageWarning());
}
}

View file

@ -0,0 +1,43 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.maker;
import bisq.desktop.util.CurrencyListItem;
import bisq.core.locale.TradeCurrency;
import com.natpryce.makeiteasy.Instantiator;
import com.natpryce.makeiteasy.Maker;
import com.natpryce.makeiteasy.Property;
import static bisq.desktop.maker.TradeCurrencyMakers.bitcoin;
import static bisq.desktop.maker.TradeCurrencyMakers.euro;
import static com.natpryce.makeiteasy.MakeItEasy.a;
import static com.natpryce.makeiteasy.MakeItEasy.with;
public class CurrencyListItemMakers {
public static final Property<bisq.desktop.util.CurrencyListItem, TradeCurrency> tradeCurrency = new Property<>();
public static final Property<CurrencyListItem, Integer> numberOfTrades = new Property<>();
public static final Instantiator<CurrencyListItem> CurrencyListItem = lookup ->
new CurrencyListItem(lookup.valueOf(tradeCurrency, bitcoin), lookup.valueOf(numberOfTrades, 0));
public static final Maker<CurrencyListItem> bitcoinItem = a(CurrencyListItem);
public static final Maker<CurrencyListItem> euroItem = a(CurrencyListItem, with(tradeCurrency, euro));
}

View file

@ -0,0 +1,84 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.maker;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import com.natpryce.makeiteasy.Instantiator;
import com.natpryce.makeiteasy.Maker;
import com.natpryce.makeiteasy.Property;
import static com.natpryce.makeiteasy.MakeItEasy.a;
import static com.natpryce.makeiteasy.MakeItEasy.with;
public class OfferMaker {
public static final Property<Offer, Long> price = new Property<>();
public static final Property<Offer, Long> minAmount = new Property<>();
public static final Property<Offer, Long> amount = new Property<>();
public static final Property<Offer, String> baseCurrencyCode = new Property<>();
public static final Property<Offer, String> counterCurrencyCode = new Property<>();
public static final Property<Offer, OfferPayload.Direction> direction = new Property<>();
public static final Property<Offer, Boolean> useMarketBasedPrice = new Property<>();
public static final Property<Offer, Double> marketPriceMargin = new Property<>();
public static final Property<Offer, String> id = new Property<>();
public static final Instantiator<Offer> Offer = lookup -> new Offer(
new OfferPayload(lookup.valueOf(id, "1234"),
0L,
null,
null,
lookup.valueOf(direction, OfferPayload.Direction.BUY),
lookup.valueOf(price, 100000L),
lookup.valueOf(marketPriceMargin, 0.0),
lookup.valueOf(useMarketBasedPrice, false),
lookup.valueOf(amount, 100000L),
lookup.valueOf(minAmount, 100000L),
lookup.valueOf(baseCurrencyCode, "BTC"),
lookup.valueOf(counterCurrencyCode, "USD"),
null,
null,
"SEPA",
"",
null,
null,
null,
null,
null,
"",
0L,
0L,
0L,
false,
0L,
0L,
0L,
0L,
false,
false,
0L,
0L,
false,
null,
null,
0));
public static final Maker<Offer> btcUsdOffer = a(Offer);
public static final Maker<Offer> btcBCHCOffer = a(Offer).but(with(counterCurrencyCode, "BCHC"));
}

View file

@ -0,0 +1,54 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.maker;
import bisq.core.btc.nodes.LocalBitcoinNode;
import bisq.core.provider.fee.FeeService;
import bisq.core.user.Preferences;
import bisq.common.config.Config;
import bisq.common.persistence.PersistenceManager;
import com.natpryce.makeiteasy.Instantiator;
import com.natpryce.makeiteasy.Property;
import com.natpryce.makeiteasy.SameValueDonor;
import static com.natpryce.makeiteasy.MakeItEasy.a;
import static com.natpryce.makeiteasy.MakeItEasy.make;
public class PreferenceMakers {
public static final Property<Preferences, PersistenceManager> storage = new Property<>();
public static final Property<Preferences, Config> config = new Property<>();
public static final Property<Preferences, FeeService> feeService = new Property<>();
public static final Property<Preferences, LocalBitcoinNode> localBitcoinNode = new Property<>();
public static final Property<Preferences, String> useTorFlagFromOptions = new Property<>();
public static final Property<Preferences, String> referralID = new Property<>();
public static final Instantiator<Preferences> Preferences = lookup -> new Preferences(
lookup.valueOf(storage, new SameValueDonor<PersistenceManager>(null)),
lookup.valueOf(config, new SameValueDonor<Config>(null)),
lookup.valueOf(feeService, new SameValueDonor<FeeService>(null)),
lookup.valueOf(localBitcoinNode, new SameValueDonor<LocalBitcoinNode>(null)),
lookup.valueOf(useTorFlagFromOptions, new SameValueDonor<String>(null)),
lookup.valueOf(referralID, new SameValueDonor<String>(null)),
Config.DEFAULT_FULL_DAO_NODE, null, null, Config.UNSPECIFIED_PORT);
public static final Preferences empty = make(a(Preferences));
}

View file

@ -0,0 +1,44 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.maker;
import bisq.core.monetary.Altcoin;
import bisq.core.monetary.Price;
import org.bitcoinj.utils.Fiat;
import com.natpryce.makeiteasy.Instantiator;
import com.natpryce.makeiteasy.Maker;
import com.natpryce.makeiteasy.Property;
import static com.natpryce.makeiteasy.MakeItEasy.a;
public class PriceMaker {
public static final Property<Price, String> currencyCode = new Property<>();
public static final Property<Price, String> priceString = new Property<>();
public static final Instantiator<Price> FiatPrice = lookup ->
new Price(Fiat.parseFiat(lookup.valueOf(currencyCode, "USD"), lookup.valueOf(priceString, "100")));
public static final Instantiator<Price> AltcoinPrice = lookup ->
new Price(Altcoin.parseAltcoin(lookup.valueOf(currencyCode, "LTC"), lookup.valueOf(priceString, "100")));
public static final Maker<Price> usdPrice = a(FiatPrice);
public static final Maker<Price> ltcPrice = a(AltcoinPrice);
}

View file

@ -0,0 +1,46 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.maker;
import bisq.core.locale.CryptoCurrency;
import bisq.core.locale.FiatCurrency;
import bisq.core.locale.TradeCurrency;
import com.natpryce.makeiteasy.Instantiator;
import com.natpryce.makeiteasy.Property;
import static com.natpryce.makeiteasy.MakeItEasy.a;
import static com.natpryce.makeiteasy.MakeItEasy.make;
import static com.natpryce.makeiteasy.MakeItEasy.with;
public class TradeCurrencyMakers {
public static final Property<TradeCurrency, String> currencyCode = new Property<>();
public static final Property<TradeCurrency, String> currencyName = new Property<>();
public static final Instantiator<bisq.core.locale.CryptoCurrency> CryptoCurrency = lookup ->
new CryptoCurrency(lookup.valueOf(currencyCode, "BTC"), lookup.valueOf(currencyName, "Bitcoin"));
public static final Instantiator<bisq.core.locale.FiatCurrency> FiatCurrency = lookup ->
new FiatCurrency(lookup.valueOf(currencyCode, "EUR"));
public static final CryptoCurrency bitcoin = make(a(CryptoCurrency));
public static final FiatCurrency euro = make(a(FiatCurrency));
public static final FiatCurrency usd = make(a(FiatCurrency).but(with(currencyCode, "USD")));
}

View file

@ -0,0 +1,44 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.maker;
import bisq.core.monetary.Altcoin;
import bisq.core.monetary.Volume;
import org.bitcoinj.utils.Fiat;
import com.natpryce.makeiteasy.Instantiator;
import com.natpryce.makeiteasy.Maker;
import com.natpryce.makeiteasy.Property;
import static com.natpryce.makeiteasy.MakeItEasy.a;
public class VolumeMaker {
public static final Property<Volume, String> currencyCode = new Property<>();
public static final Property<Volume, String> volumeString = new Property<>();
public static final Instantiator<Volume> FiatVolume = lookup ->
new Volume(Fiat.parseFiat(lookup.valueOf(currencyCode, "USD"), lookup.valueOf(volumeString, "100")));
public static final Instantiator<Volume> AltcoinVolume = lookup ->
new Volume(Altcoin.parseAltcoin(lookup.valueOf(currencyCode, "LTC"), lookup.valueOf(volumeString, "100")));
public static final Maker<Volume> usdVolume = a(FiatVolume);
public static final Maker<Volume> ltcVolume = a(AltcoinVolume);
}

View file

@ -0,0 +1,121 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.util;
import bisq.core.locale.CryptoCurrency;
import bisq.core.locale.FiatCurrency;
import bisq.core.locale.TradeCurrency;
import bisq.core.user.Preferences;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.Currency;
import java.util.List;
import java.util.Locale;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class CurrencyListTest {
private static final Locale locale = new Locale("en", "US");
private static final TradeCurrency USD = new FiatCurrency(Currency.getInstance("USD"), locale);
private static final TradeCurrency RUR = new FiatCurrency(Currency.getInstance("RUR"), locale);
private static final TradeCurrency BTC = new CryptoCurrency("BTC", "Bitcoin");
private static final TradeCurrency ETH = new CryptoCurrency("ETH", "Ether");
private static final TradeCurrency BSQ = new CryptoCurrency("BSQ", "Bisq Token");
private Preferences preferences;
private List<CurrencyListItem> delegate;
private CurrencyList testedEntity;
@Before
public void setUp() {
Locale.setDefault(locale);
CurrencyPredicates predicates = mock(CurrencyPredicates.class);
when(predicates.isCryptoCurrency(USD)).thenReturn(false);
when(predicates.isCryptoCurrency(RUR)).thenReturn(false);
when(predicates.isCryptoCurrency(BTC)).thenReturn(true);
when(predicates.isCryptoCurrency(ETH)).thenReturn(true);
when(predicates.isFiatCurrency(USD)).thenReturn(true);
when(predicates.isFiatCurrency(RUR)).thenReturn(true);
when(predicates.isFiatCurrency(BTC)).thenReturn(false);
when(predicates.isFiatCurrency(ETH)).thenReturn(false);
this.preferences = mock(Preferences.class);
this.delegate = new ArrayList<>();
this.testedEntity = new CurrencyList(delegate, preferences, predicates);
}
@Test
public void testUpdateWhenSortNumerically() {
when(preferences.isSortMarketCurrenciesNumerically()).thenReturn(true);
List<TradeCurrency> currencies = Lists.newArrayList(USD, RUR, USD, ETH, ETH, BTC);
testedEntity.updateWithCurrencies(currencies, null);
List<CurrencyListItem> expected = Lists.newArrayList(
new CurrencyListItem(USD, 2),
new CurrencyListItem(RUR, 1),
new CurrencyListItem(ETH, 2),
new CurrencyListItem(BTC, 1));
assertEquals(expected, delegate);
}
@Test
public void testUpdateWhenNotSortNumerically() {
when(preferences.isSortMarketCurrenciesNumerically()).thenReturn(false);
List<TradeCurrency> currencies = Lists.newArrayList(USD, RUR, USD, ETH, ETH, BTC);
testedEntity.updateWithCurrencies(currencies, null);
List<CurrencyListItem> expected = Lists.newArrayList(
new CurrencyListItem(RUR, 1),
new CurrencyListItem(USD, 2),
new CurrencyListItem(BTC, 1),
new CurrencyListItem(ETH, 2));
assertEquals(expected, delegate);
}
@Test
public void testUpdateWhenSortNumericallyAndFirstSpecified() {
when(preferences.isSortMarketCurrenciesNumerically()).thenReturn(true);
List<TradeCurrency> currencies = Lists.newArrayList(USD, RUR, USD, ETH, ETH, BTC);
CurrencyListItem first = new CurrencyListItem(BSQ, 5);
testedEntity.updateWithCurrencies(currencies, first);
List<CurrencyListItem> expected = Lists.newArrayList(
first,
new CurrencyListItem(USD, 2),
new CurrencyListItem(RUR, 1),
new CurrencyListItem(ETH, 2),
new CurrencyListItem(BTC, 1));
assertEquals(expected, delegate);
}
}

View file

@ -0,0 +1,135 @@
package bisq.desktop.util;
import bisq.core.locale.Res;
import bisq.core.monetary.Volume;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
import bisq.core.util.coin.ImmutableCoinFormatter;
import bisq.core.util.coin.CoinFormatter;
import bisq.common.config.Config;
import org.bitcoinj.core.Coin;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import org.junit.Before;
import org.junit.Test;
import static bisq.desktop.maker.OfferMaker.btcUsdOffer;
import static bisq.desktop.maker.VolumeMaker.usdVolume;
import static bisq.desktop.maker.VolumeMaker.volumeString;
import static com.natpryce.makeiteasy.MakeItEasy.make;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class DisplayUtilsTest {
private final CoinFormatter formatter = new ImmutableCoinFormatter(Config.baseCurrencyNetworkParameters().getMonetaryFormat());
@Before
public void setUp() {
Locale.setDefault(new Locale("en", "US"));
Res.setBaseCurrencyCode("BTC");
Res.setBaseCurrencyName("Bitcoin");
}
@Test
public void testFormatAccountAge() {
assertEquals("0 days", DisplayUtils.formatAccountAge(TimeUnit.HOURS.toMillis(23)));
assertEquals("0 days", DisplayUtils.formatAccountAge(0));
assertEquals("0 days", DisplayUtils.formatAccountAge(-1));
assertEquals("1 day", DisplayUtils.formatAccountAge(TimeUnit.DAYS.toMillis(1)));
assertEquals("2 days", DisplayUtils.formatAccountAge(TimeUnit.DAYS.toMillis(2)));
assertEquals("30 days", DisplayUtils.formatAccountAge(TimeUnit.DAYS.toMillis(30)));
assertEquals("60 days", DisplayUtils.formatAccountAge(TimeUnit.DAYS.toMillis(60)));
}
@Test
public void testFormatVolume() {
assertEquals("1", DisplayUtils.formatVolume(make(btcUsdOffer), true, 4));
assertEquals("100", DisplayUtils.formatVolume(make(usdVolume)));
assertEquals("1775", DisplayUtils.formatVolume(make(usdVolume.but(with(volumeString, "1774.62")))));
}
@Test
public void testFormatSameVolume() {
Offer offer = mock(Offer.class);
Volume btc = Volume.parse("0.10", "BTC");
when(offer.getMinVolume()).thenReturn(btc);
when(offer.getVolume()).thenReturn(btc);
assertEquals("0.10000000", DisplayUtils.formatVolume(offer.getVolume()));
}
@Test
public void testFormatDifferentVolume() {
Offer offer = mock(Offer.class);
Volume btcMin = Volume.parse("0.10", "BTC");
Volume btcMax = Volume.parse("0.25", "BTC");
when(offer.isRange()).thenReturn(true);
when(offer.getMinVolume()).thenReturn(btcMin);
when(offer.getVolume()).thenReturn(btcMax);
assertEquals("0.10000000 - 0.25000000", DisplayUtils.formatVolume(offer, false, 0));
}
@Test
public void testFormatNullVolume() {
Offer offer = mock(Offer.class);
when(offer.getMinVolume()).thenReturn(null);
when(offer.getVolume()).thenReturn(null);
assertEquals("", DisplayUtils.formatVolume(offer.getVolume()));
}
@Test
public void testFormatSameAmount() {
Offer offer = mock(Offer.class);
when(offer.getMinAmount()).thenReturn(Coin.valueOf(10000000));
when(offer.getAmount()).thenReturn(Coin.valueOf(10000000));
assertEquals("0.10", DisplayUtils.formatAmount(offer, formatter));
}
@Test
public void testFormatDifferentAmount() {
OfferPayload offerPayload = mock(OfferPayload.class);
Offer offer = new Offer(offerPayload);
when(offerPayload.getMinAmount()).thenReturn(10000000L);
when(offerPayload.getAmount()).thenReturn(20000000L);
assertEquals("0.10 - 0.20", DisplayUtils.formatAmount(offer, formatter));
}
@Test
public void testFormatAmountWithAlignmenWithDecimals() {
OfferPayload offerPayload = mock(OfferPayload.class);
Offer offer = new Offer(offerPayload);
when(offerPayload.getMinAmount()).thenReturn(10000000L);
when(offerPayload.getAmount()).thenReturn(20000000L);
assertEquals("0.1000 - 0.2000", DisplayUtils.formatAmount(offer, 4, true, 15, formatter));
}
@Test
public void testFormatAmountWithAlignmenWithDecimalsNoRange() {
OfferPayload offerPayload = mock(OfferPayload.class);
Offer offer = new Offer(offerPayload);
when(offerPayload.getMinAmount()).thenReturn(10000000L);
when(offerPayload.getAmount()).thenReturn(10000000L);
assertEquals("0.1000", DisplayUtils.formatAmount(offer, 4, true, 15, formatter));
}
@Test
public void testFormatNullAmount() {
Offer offer = mock(Offer.class);
when(offer.getMinAmount()).thenReturn(null);
when(offer.getAmount()).thenReturn(null);
assertEquals("", DisplayUtils.formatAmount(offer, formatter));
}
}

View file

@ -0,0 +1,156 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.util;
import bisq.core.locale.GlobalSettings;
import bisq.core.locale.Res;
import bisq.core.locale.TradeCurrency;
import bisq.core.monetary.Price;
import bisq.core.provider.price.MarketPrice;
import bisq.core.provider.price.PriceFeedService;
import bisq.core.user.DontShowAgainLookup;
import bisq.core.user.Preferences;
import bisq.core.util.coin.BsqFormatter;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.CoinMaker;
import javafx.util.StringConverter;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import static bisq.desktop.maker.TradeCurrencyMakers.bitcoin;
import static bisq.desktop.maker.TradeCurrencyMakers.euro;
import static com.natpryce.makeiteasy.MakeItEasy.a;
import static com.natpryce.makeiteasy.MakeItEasy.make;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static org.bitcoinj.core.CoinMaker.oneBitcoin;
import static org.bitcoinj.core.CoinMaker.satoshis;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class GUIUtilTest {
@Before
public void setup() {
Locale.setDefault(new Locale("en", "US"));
GlobalSettings.setLocale(new Locale("en", "US"));
Res.setBaseCurrencyCode("BTC");
Res.setBaseCurrencyName("Bitcoin");
}
@Test
public void testTradeCurrencyConverter() {
Map<String, Integer> offerCounts = new HashMap<>() {{
put("BTC", 11);
put("EUR", 10);
}};
StringConverter<TradeCurrency> tradeCurrencyConverter = GUIUtil.getTradeCurrencyConverter(
Res.get("shared.oneOffer"),
Res.get("shared.multipleOffers"),
offerCounts
);
assertEquals("✦ Bitcoin (BTC) - 11 offers", tradeCurrencyConverter.toString(bitcoin));
assertEquals("★ Euro (EUR) - 10 offers", tradeCurrencyConverter.toString(euro));
}
@Test
public void testOpenURLWithCampaignParameters() {
Preferences preferences = mock(Preferences.class);
DontShowAgainLookup.setPreferences(preferences);
GUIUtil.setPreferences(preferences);
when(preferences.showAgain("warnOpenURLWhenTorEnabled")).thenReturn(false);
when(preferences.getUserLanguage()).thenReturn("en");
/* PowerMockito.mockStatic(Utilities.class);
ArgumentCaptor<URI> captor = ArgumentCaptor.forClass(URI.class);
PowerMockito.doNothing().when(Utilities.class, "openURI", captor.capture());
GUIUtil.openWebPage("https://bisq.network");
assertEquals("https://bisq.network?utm_source=desktop-client&utm_medium=in-app-link&utm_campaign=language_en", captor.getValue().toString());
GUIUtil.openWebPage("https://docs.bisq.network/trading-rules.html#f2f-trading");
assertEquals("https://docs.bisq.network/trading-rules.html?utm_source=desktop-client&utm_medium=in-app-link&utm_campaign=language_en#f2f-trading", captor.getValue().toString());
*/
}
@Test
public void testOpenURLWithoutCampaignParameters() {
Preferences preferences = mock(Preferences.class);
DontShowAgainLookup.setPreferences(preferences);
GUIUtil.setPreferences(preferences);
when(preferences.showAgain("warnOpenURLWhenTorEnabled")).thenReturn(false);
/*
PowerMockito.mockStatic(Utilities.class);
ArgumentCaptor<URI> captor = ArgumentCaptor.forClass(URI.class);
PowerMockito.doNothing().when(Utilities.class, "openURI", captor.capture());
GUIUtil.openWebPage("https://www.github.com");
assertEquals("https://www.github.com", captor.getValue().toString());
*/
}
@Test
public void testGetBsqInUsd() {
PriceFeedService priceFeedService = mock(PriceFeedService.class);
when(priceFeedService.getMarketPrice("USD"))
.thenReturn(new MarketPrice("USD", 12345.6789, 0, true));
Coin oneBsq = Coin.valueOf(100);
Price avgPrice = Price.valueOf("BSQ", 10000);
assertEquals("1.23 USD", GUIUtil.getBsqInUsd(avgPrice, oneBsq, priceFeedService, new BsqFormatter()));
}
@Test
public void percentageOfTradeAmount_higherFeeAsMin() {
Coin fee = make(a(CoinMaker.Coin).but(with(satoshis, 20000L)));
Coin min = make(a(CoinMaker.Coin).but(with(satoshis, 10000L)));
assertEquals(" (0.02% of trade amount)", GUIUtil.getPercentageOfTradeAmount(fee, oneBitcoin, min));
}
@Test
public void percentageOfTradeAmount_minFee() {
Coin fee = make(a(CoinMaker.Coin).but(with(satoshis, 10000L)));
Coin min = make(a(CoinMaker.Coin).but(with(satoshis, 10000L)));
assertEquals(" (required minimum)",
GUIUtil.getPercentageOfTradeAmount(fee, oneBitcoin, min));
}
@Test
public void percentageOfTradeAmount_minFeeZERO() {
Coin fee = make(a(CoinMaker.Coin).but(with(satoshis, 10000L)));
assertEquals(" (0.01% of trade amount)",
GUIUtil.getPercentageOfTradeAmount(fee, oneBitcoin, Coin.ZERO));
}
}

View file

@ -0,0 +1,61 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.util;
import bisq.core.locale.Res;
import bisq.core.util.coin.ImmutableCoinFormatter;
import bisq.core.util.coin.CoinFormatter;
import bisq.common.config.Config;
import org.bitcoinj.core.CoinMaker;
import java.util.Locale;
import org.junit.Before;
import org.junit.Test;
import static com.natpryce.makeiteasy.MakeItEasy.a;
import static com.natpryce.makeiteasy.MakeItEasy.make;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static org.bitcoinj.core.CoinMaker.oneBitcoin;
import static org.bitcoinj.core.CoinMaker.satoshis;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
public class ImmutableCoinFormatterTest {
private final CoinFormatter formatter = new ImmutableCoinFormatter(Config.baseCurrencyNetworkParameters().getMonetaryFormat());
@Before
public void setUp() {
Locale.setDefault(new Locale("en", "US"));
Res.setBaseCurrencyCode("BTC");
Res.setBaseCurrencyName("Bitcoin");
}
@Test
public void testFormatCoin() {
assertEquals("1.00", formatter.formatCoin(oneBitcoin));
assertEquals("1.0000", formatter.formatCoin(oneBitcoin, 4));
assertEquals("1.00", formatter.formatCoin(oneBitcoin, 5));
assertEquals("0.000001", formatter.formatCoin(make(a(CoinMaker.Coin).but(with(satoshis, 100L)))));
assertEquals("0.00000001", formatter.formatCoin(make(a(CoinMaker.Coin).but(with(satoshis, 1L)))));
}
}

View file

@ -0,0 +1,156 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.util;
import java.util.Arrays;
import java.util.stream.Stream;
import org.junit.Assert;
import org.junit.Test;
public class MovingAverageUtilsTest {
private static final int NAN = -99;
private static int[] calcMA(int period, int[] input) {
System.out.println("Input:");
System.out.println(Arrays.toString(input));
Stream<Number> streamInput =
Arrays
.stream(input)
.boxed()
.map(x -> x == NAN ? Double.NaN : x);
int[] output = MovingAverageUtils
.simpleMovingAverage(streamInput, period)
.mapToInt(x -> Double.isFinite(x) ? (int) Math.round(x) : NAN)
.toArray();
System.out.println("Output:");
System.out.println(Arrays.toString(output));
return output;
}
private static void testMA(int period, int[] input, int[] expected) {
var output = calcMA(period, input);
Assert.assertArrayEquals(output, expected);
}
@Test
public void normalConditions() {
testMA(
2,
new int[]{10, 20, 30, 40},
new int[]{NAN, 15, 25, 35}
);
}
@Test
public void inputContainsNaNs0() {
testMA(
2,
new int[]{NAN, 20, 30, 40},
new int[]{NAN, NAN, 25, 35}
);
}
@Test
public void inputContainsNaNs1() {
testMA(
2,
new int[]{10, NAN, 30, 40},
new int[]{NAN, NAN, NAN, 35}
);
}
@Test
public void inputContainsNaNs2() {
testMA(
2,
new int[]{10, NAN, NAN, 40},
new int[]{NAN, NAN, NAN, NAN}
);
}
@Test
public void inputContainsNaNs3() {
testMA(
2,
new int[]{10, NAN, 30, NAN, 40},
new int[]{NAN, NAN, NAN, NAN, NAN}
);
}
@Test
public void nonsensicalPeriod0() {
testMA(
1,
new int[]{10, 20},
new int[]{10, 20}
);
}
@Test(expected = IllegalArgumentException.class)
public void nonsensicalPeriod1() {
var impossible = new int[]{};
testMA(
0,
new int[]{10, 20},
impossible
);
}
@Test(expected = IllegalArgumentException.class)
public void nonsensicalPeriod2() {
var impossible = new int[]{};
testMA(
-1,
new int[]{10, 20},
impossible
);
}
@Test
public void tooLittleData0() {
testMA(
3,
new int[]{},
new int[]{NAN, NAN}
);
}
@Test
public void tooLittleData1() {
testMA(
3,
new int[]{10},
new int[]{NAN, NAN}
);
}
@Test
public void tooLittleData2() {
testMA(
3,
new int[]{10, 20},
new int[]{NAN, NAN}
);
}
}

View file

@ -0,0 +1,28 @@
package bisq.desktop.util.validation;
import bisq.core.locale.Res;
import java.util.Locale;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
public class AccountNrValidatorTest {
@Before
public void setup() {
Locale.setDefault(new Locale("en", "US"));
Res.setBaseCurrencyCode("BTC");
Res.setBaseCurrencyName("Bitcoin");
}
@Test
public void testValidationForArgentina() {
AccountNrValidator validator = new AccountNrValidator("AR");
assertTrue(validator.validate("4009041813520").isValid);
assertTrue(validator.validate("035-005198/5").isValid);
}
}

View file

@ -0,0 +1,40 @@
package bisq.desktop.util.validation;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.util.validation.RegexValidator;
import bisq.common.config.BaseCurrencyNetwork;
import bisq.common.config.Config;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class AdvancedCashValidatorTest {
@Before
public void setup() {
final BaseCurrencyNetwork baseCurrencyNetwork = Config.baseCurrencyNetwork();
final String currencyCode = baseCurrencyNetwork.getCurrencyCode();
Res.setBaseCurrencyCode(currencyCode);
Res.setBaseCurrencyName(baseCurrencyNetwork.getCurrencyName());
CurrencyUtil.setBaseCurrencyCode(currencyCode);
}
@Test
public void validate(){
AdvancedCashValidator validator = new AdvancedCashValidator(
new EmailValidator(),
new RegexValidator()
);
assertTrue(validator.validate("U123456789012").isValid);
assertTrue(validator.validate("test@user.com").isValid);
assertFalse(validator.validate("").isValid);
assertFalse(validator.validate(null).isValid);
assertFalse(validator.validate("123456789012").isValid);
}
}

View file

@ -0,0 +1,31 @@
package bisq.desktop.util.validation;
import bisq.core.locale.Res;
import java.util.Locale;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class BranchIdValidatorTest {
@Before
public void setup() {
Locale.setDefault(new Locale("en", "US"));
Res.setBaseCurrencyCode("BTC");
Res.setBaseCurrencyName("Bitcoin");
}
@Test
public void testValidationForArgentina() {
BranchIdValidator validator = new BranchIdValidator("AR");
assertTrue(validator.validate("0590").isValid);
assertFalse(validator.validate("05901").isValid);
}
}

View file

@ -0,0 +1,74 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.util.validation;
import bisq.common.config.BaseCurrencyNetwork;
import bisq.common.config.Config;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.util.coin.CoinFormatter;
import bisq.core.util.coin.ImmutableCoinFormatter;
import org.bitcoinj.core.Coin;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class BtcValidatorTest {
private final CoinFormatter coinFormatter = new ImmutableCoinFormatter(Config.baseCurrencyNetworkParameters().getMonetaryFormat());
@Before
public void setup() {
final BaseCurrencyNetwork baseCurrencyNetwork = Config.baseCurrencyNetwork();
final String currencyCode = baseCurrencyNetwork.getCurrencyCode();
Res.setBaseCurrencyCode(currencyCode);
Res.setBaseCurrencyName(baseCurrencyNetwork.getCurrencyName());
CurrencyUtil.setBaseCurrencyCode(currencyCode);
}
@Test
public void testIsValid() {
BtcValidator validator = new BtcValidator(coinFormatter);
assertTrue(validator.validate("1").isValid);
assertTrue(validator.validate("0,1").isValid);
assertTrue(validator.validate("0.1").isValid);
assertTrue(validator.validate(",1").isValid);
assertTrue(validator.validate(".1").isValid);
assertTrue(validator.validate("0.12345678").isValid);
assertFalse(validator.validate(Coin.SATOSHI.toPlainString()).isValid); // below dust
assertFalse(validator.validate(null).isValid);
assertFalse(validator.validate("").isValid);
assertFalse(validator.validate("0").isValid);
assertFalse(validator.validate("0.0").isValid);
assertFalse(validator.validate("0,1,1").isValid);
assertFalse(validator.validate("0.1.1").isValid);
assertFalse(validator.validate("0,000.1").isValid);
assertFalse(validator.validate("0.000,1").isValid);
assertFalse(validator.validate("0.123456789").isValid);
assertFalse(validator.validate("-1").isValid);
// assertFalse(validator.validate(NetworkParameters.MAX_MONEY.toPlainString()).isValid);
}
}

View file

@ -0,0 +1,73 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.util.validation;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.common.config.BaseCurrencyNetwork;
import bisq.common.config.Config;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class FiatVolumeValidatorTest {
@Before
public void setup() {
final BaseCurrencyNetwork baseCurrencyNetwork = Config.baseCurrencyNetwork();
final String currencyCode = baseCurrencyNetwork.getCurrencyCode();
Res.setBaseCurrencyCode(currencyCode);
Res.setBaseCurrencyName(baseCurrencyNetwork.getCurrencyName());
CurrencyUtil.setBaseCurrencyCode(currencyCode);
}
@Test
public void testValidate() {
FiatVolumeValidator validator = new FiatVolumeValidator();
assertTrue(validator.validate("1").isValid);
assertTrue(validator.validate("1,1").isValid);
assertTrue(validator.validate("1.1").isValid);
assertTrue(validator.validate(",1").isValid);
assertTrue(validator.validate(".1").isValid);
assertTrue(validator.validate("0.01").isValid);
assertTrue(validator.validate("1000000.00").isValid);
assertTrue(validator.validate(String.valueOf(validator.getMinValue())).isValid);
assertTrue(validator.validate(String.valueOf(validator.getMaxValue())).isValid);
assertFalse(validator.validate(null).isValid);
assertFalse(validator.validate("").isValid);
assertFalse(validator.validate("a").isValid);
assertFalse(validator.validate("2a").isValid);
assertFalse(validator.validate("a2").isValid);
assertFalse(validator.validate("0").isValid);
assertFalse(validator.validate("-1").isValid);
assertFalse(validator.validate("0.0").isValid);
assertFalse(validator.validate("0,1,1").isValid);
assertFalse(validator.validate("0.1.1").isValid);
assertFalse(validator.validate("1,000.1").isValid);
assertFalse(validator.validate("1.000,1").isValid);
assertFalse(validator.validate("0.009").isValid);
assertFalse(validator.validate(String.valueOf(validator.getMinValue() - 1)).isValid);
assertFalse(validator.validate(String.valueOf(Double.MIN_VALUE)).isValid);
}
}

View file

@ -0,0 +1,61 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.util.validation;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.util.validation.RegexValidator;
import bisq.common.config.BaseCurrencyNetwork;
import bisq.common.config.Config;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class InteracETransferAnswerValidatorTest {
@Before
public void setup() {
final BaseCurrencyNetwork baseCurrencyNetwork = Config.baseCurrencyNetwork();
final String currencyCode = baseCurrencyNetwork.getCurrencyCode();
Res.setBaseCurrencyCode(currencyCode);
Res.setBaseCurrencyName(baseCurrencyNetwork.getCurrencyName());
CurrencyUtil.setBaseCurrencyCode(currencyCode);
}
@Test
public void validate() throws Exception {
InteracETransferAnswerValidator validator = new InteracETransferAnswerValidator(new LengthValidator(), new RegexValidator());
assertTrue(validator.validate("abcdefghijklmnopqrstuvwxy").isValid);
assertTrue(validator.validate("ABCDEFGHIJKLMNOPQRSTUVWXY").isValid);
assertTrue(validator.validate("1234567890").isValid);
assertTrue(validator.validate("zZ-").isValid);
assertFalse(validator.validate(null).isValid); // null
assertFalse(validator.validate("").isValid); // empty
assertFalse(validator.validate("two words").isValid); // two words
assertFalse(validator.validate("ab").isValid); // too short
assertFalse(validator.validate("abcdefghijklmnopqrstuvwxyz").isValid); // too long
assertFalse(validator.validate("abc !@#").isValid); // invalid characters
}
}

View file

@ -0,0 +1,60 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.util.validation;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.util.validation.RegexValidator;
import bisq.common.config.BaseCurrencyNetwork;
import bisq.common.config.Config;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class InteracETransferQuestionValidatorTest {
@Before
public void setup() {
final BaseCurrencyNetwork baseCurrencyNetwork = Config.baseCurrencyNetwork();
final String currencyCode = baseCurrencyNetwork.getCurrencyCode();
Res.setBaseCurrencyCode(currencyCode);
Res.setBaseCurrencyName(baseCurrencyNetwork.getCurrencyName());
CurrencyUtil.setBaseCurrencyCode(currencyCode);
}
@Test
public void validate() throws Exception {
InteracETransferQuestionValidator validator = new InteracETransferQuestionValidator(new LengthValidator(), new RegexValidator());
assertTrue(validator.validate("abcdefghijklmnopqrstuvwxyz").isValid);
assertTrue(validator.validate("ABCDEFGHIJKLMNOPQRSTUVWXYZ").isValid);
assertTrue(validator.validate("1234567890").isValid);
assertTrue(validator.validate("' _ , . ? -").isValid);
assertTrue(validator.validate("what is 2-1?").isValid);
assertFalse(validator.validate(null).isValid); // null
assertFalse(validator.validate("").isValid); // empty
assertFalse(validator.validate("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ").isValid); // too long
assertFalse(validator.validate("abc !@#").isValid); // invalid characters
}
}

View file

@ -0,0 +1,68 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.util.validation;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.util.validation.RegexValidator;
import bisq.common.config.BaseCurrencyNetwork;
import bisq.common.config.Config;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class InteracETransferValidatorTest {
@Before
public void setup() {
final BaseCurrencyNetwork baseCurrencyNetwork = Config.baseCurrencyNetwork();
final String currencyCode = baseCurrencyNetwork.getCurrencyCode();
Res.setBaseCurrencyCode(currencyCode);
Res.setBaseCurrencyName(baseCurrencyNetwork.getCurrencyName());
CurrencyUtil.setBaseCurrencyCode(currencyCode);
}
@Test
public void validate() throws Exception {
InteracETransferValidator validator = new InteracETransferValidator(
new EmailValidator(),
new InteracETransferQuestionValidator(new LengthValidator(), new RegexValidator()),
new InteracETransferAnswerValidator(new LengthValidator(), new RegexValidator())
);
assertTrue(validator.validate("name@domain.tld").isValid);
assertTrue(validator.validate("n1.n2@c.dd").isValid);
assertTrue(validator.validate("+1 236 123-4567").isValid);
assertTrue(validator.validate("15061234567").isValid);
assertTrue(validator.validate("1 289 784 2134").isValid);
assertTrue(validator.validate("+1-514-654-7412").isValid);
assertFalse(validator.validate("abc@.de").isValid); // Domain name missing
assertFalse(validator.validate("abc@d.e").isValid); // TLD too short
assertFalse(validator.validate("2361234567").isValid); // Prefix for North America missing (often required for local calls as well)
assertFalse(validator.validate("+150612345678").isValid); // Too long
assertFalse(validator.validate("1289784213").isValid); // Too short
assertFalse(validator.validate("+1 555 123-4567").isValid); // Non-Canadian area code
assertFalse(validator.validate("+1 236 1234-567").isValid); // Wrong grouping
}
}

View file

@ -0,0 +1,72 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.util.validation;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.common.config.BaseCurrencyNetwork;
import bisq.common.config.Config;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class LengthValidatorTest {
@Before
public void setup() {
final BaseCurrencyNetwork baseCurrencyNetwork = Config.baseCurrencyNetwork();
final String currencyCode = baseCurrencyNetwork.getCurrencyCode();
Res.setBaseCurrencyCode(currencyCode);
Res.setBaseCurrencyName(baseCurrencyNetwork.getCurrencyName());
CurrencyUtil.setBaseCurrencyCode(currencyCode);
}
@Test
public void validate() throws Exception {
LengthValidator validator = new LengthValidator();
assertTrue(validator.validate("").isValid);
assertTrue(validator.validate(null).isValid);
assertTrue(validator.validate("123456789").isValid);
validator.setMinLength(2);
validator.setMaxLength(5);
assertTrue(validator.validate("12").isValid);
assertTrue(validator.validate("12345").isValid);
assertFalse(validator.validate("1").isValid); // too short
assertFalse(validator.validate("").isValid); // too short
assertFalse(validator.validate(null).isValid); // too short
assertFalse(validator.validate("123456789").isValid); // too long
LengthValidator validator2 = new LengthValidator(2, 5);
assertTrue(validator2.validate("12").isValid);
assertTrue(validator2.validate("12345").isValid);
assertFalse(validator2.validate("1").isValid); // too short
assertFalse(validator2.validate("").isValid); // too short
assertFalse(validator2.validate(null).isValid); // too short
assertFalse(validator2.validate("123456789").isValid); // too long
}
}

View file

@ -0,0 +1,30 @@
package bisq.desktop.util.validation;
import bisq.core.locale.Res;
import java.util.Locale;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class NationalAccountIdValidatorTest {
@Before
public void setup() {
Locale.setDefault(new Locale("en", "US"));
Res.setBaseCurrencyCode("BTC");
Res.setBaseCurrencyName("Bitcoin");
}
@Test
public void testValidationForArgentina(){
NationalAccountIdValidator validator = new NationalAccountIdValidator("AR");
assertTrue(validator.validate("2850590940090418135201").isValid);
final String wrongNationalAccountId = "285059094009041813520";
assertFalse(validator.validate(wrongNationalAccountId).isValid);
assertEquals("CBU number must consist of 22 numbers.", validator.validate(wrongNationalAccountId).errorMessage);
}
}

View file

@ -0,0 +1,299 @@
package bisq.desktop.util.validation;
import bisq.core.locale.Res;
import bisq.core.util.validation.InputValidator.ValidationResult;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class PhoneNumberValidatorTest {
private PhoneNumberValidator validator;
private ValidationResult validationResult;
@Before
public void setup() {
Res.setup();
}
@Test
public void testMissingCountryCode() {
validator = new PhoneNumberValidator();
validationResult = validator.validate("+12124567890");
assertFalse("Should not be valid if validator's country code is missing", validationResult.isValid);
assertEquals(Res.get("validation.phone.missingCountryCode"), validationResult.errorMessage);
assertNull(validator.getNormalizedPhoneNumber());
}
@Test
public void testNoInput() {
validator = new PhoneNumberValidator("AT");
validationResult = validator.validate("");
assertFalse("'' should not be a valid number in AT", validationResult.isValid);
assertEquals(Res.get("validation.empty"), validationResult.errorMessage);
assertNull(validator.getNormalizedPhoneNumber());
validationResult = validator.validate(null);
assertFalse("'' should not be a valid number in AT", validationResult.isValid);
assertEquals(Res.get("validation.empty"), validationResult.errorMessage);
assertNull(validator.getNormalizedPhoneNumber());
}
@Test
public void testAustriaNumbers() {
validator = new PhoneNumberValidator("AT");
assertEquals(validator.getCallingCode(), "43");
validationResult = validator.validate("(0316) 214 4366");
assertTrue(validationResult.isValid);
assertEquals("+4303162144366", validator.getNormalizedPhoneNumber());
// 1 Vienna
validationResult = validator.validate("+43 1 214-3512");
assertTrue(validationResult.isValid);
assertEquals("+4312143512", validator.getNormalizedPhoneNumber());
// 1 Vienna cell
validationResult = validator.validate("+43 1 650 454 0987");
assertTrue(validationResult.isValid);
assertEquals("+4316504540987", validator.getNormalizedPhoneNumber());
// 676 T-Mobile
validationResult = validator.validate("0676 2241647");
assertTrue(validationResult.isValid);
assertEquals("+4306762241647", validator.getNormalizedPhoneNumber());
}
@Test
public void testInvalidAustriaNumbers() {
validator = new PhoneNumberValidator("AT"); // AT country code is +43
validationResult = validator.validate("+43 1 214");
assertFalse("+43 1 214 should not be a valid number in AT", validationResult.isValid);
assertEquals(Res.get("validation.phone.insufficientDigits", "+43 1 214"), validationResult.errorMessage);
assertNull(validator.getNormalizedPhoneNumber());
validationResult = validator.validate("+42 1 650 454 0987");
assertFalse("+42 1 650 454 0987 should not be a valid number in AT", validationResult.isValid);
assertEquals(Res.get("validation.phone.invalidDialingCode", "+42 1 650 454 0987", "AT", validator.getCallingCode()),
validationResult.errorMessage);
assertNull(validator.getNormalizedPhoneNumber());
}
@Test
public void testDominicanRepublicNumbers() {
validator = new PhoneNumberValidator("DO");
assertEquals(validator.getCallingCode(), "1");
validationResult = validator.validate("1829-123 4567");
assertTrue(validationResult.isValid);
assertEquals("+18291234567", validator.getNormalizedPhoneNumber());
validationResult = validator.validate("+18091234567");
assertTrue(validationResult.isValid);
assertEquals("+18091234567", validator.getNormalizedPhoneNumber());
validationResult = validator.validate("+1 (849) 543-0098");
assertTrue(validationResult.isValid);
assertEquals("+18495430098", validator.getNormalizedPhoneNumber());
}
@Test
public void testBrazilNumbers() {
validator = new PhoneNumberValidator("BR");
assertEquals(validator.getCallingCode(), "55");
validationResult = validator.validate("11 3333 5555");
assertTrue(validationResult.isValid);
assertEquals("+551133335555", validator.getNormalizedPhoneNumber());
// Sao Paulo cell
validationResult = validator.validate("55 11 9 3444 2567");
assertTrue(validationResult.isValid);
assertEquals("+5511934442567", validator.getNormalizedPhoneNumber());
// 85 Fortaleza landline using long-distance carrier OI (31)
validationResult = validator.validate("031 85 4433 8432");
assertTrue(validationResult.isValid);
assertEquals("+550318544338432", validator.getNormalizedPhoneNumber());
}
@Test
public void testCanadaNumbers() {
validator = new PhoneNumberValidator("CA");
assertEquals(validator.getCallingCode(), "1");
validationResult = validator.validate("867 374-8299");
assertTrue(validationResult.isValid);
assertEquals("+18673748299", validator.getNormalizedPhoneNumber());
validationResult = validator.validate("+1 306-374-8299 ");
assertTrue(validationResult.isValid);
assertEquals("+13063748299", validator.getNormalizedPhoneNumber());
validationResult = validator.validate(" (709) 374-8299");
assertTrue(validationResult.isValid);
assertEquals("+17093748299", validator.getNormalizedPhoneNumber());
}
@Test
public void testInvalidCanadaNumber() {
validator = new PhoneNumberValidator("CA");
validationResult = validator.validate("+2 1 650 454 0987");
assertFalse("+2 1 650 454 0987 should not be a valid number in CA", validationResult.isValid);
assertEquals(Res.get("validation.phone.invalidDialingCode", "+2 1 650 454 0987", "CA", validator.getCallingCode()),
validationResult.errorMessage);
assertNull(validator.getNormalizedPhoneNumber());
}
@Test
public void testChinaNumbers() {
validator = new PhoneNumberValidator("CN");
assertEquals(validator.getCallingCode(), "86");
// In major cities, landline-numbers consist of a two-digit area code followed
// by an eight-digit inner-number. In other places, landline-numbers consist of
// a three-digit area code followed by a seven- or eight-digit inner-number.
// The numbers of mobile phones consist of eleven digits. Hard to validate.
// 10 Beijing
validationResult = validator.validate(" 10 4534 8214");
assertTrue(validationResult.isValid);
assertEquals("+861045348214", validator.getNormalizedPhoneNumber());
// 21 Shanghai
validationResult = validator.validate("+86 (21) 3422-5814");
assertTrue(validationResult.isValid);
assertEquals("+862134225814", validator.getNormalizedPhoneNumber());
// 18x Mobile phone numbers have 11 digits in the format 1xx-xxxx-xxxx,
// in which the first three digits (e.g. 13x, 14x,15x,17x and 18x) designate
// the mobile phone service provider.
validationResult = validator.validate("180-4353-7877"); // no country code prefix
assertTrue(validationResult.isValid);
assertEquals("+8618043537877", validator.getNormalizedPhoneNumber());
}
@Test
public void testJapanNumbers() {
validator = new PhoneNumberValidator("JP");
assertEquals(validator.getCallingCode(), "81");
// 11 Sapporo 011-XXX-XXXX
validationResult = validator.validate("11 367-2345");
assertTrue(validationResult.isValid);
assertEquals("+81113672345", validator.getNormalizedPhoneNumber());
// 0476 Narita, 0476-XX-XXXX
validationResult = validator.validate("0476 87 2055");
assertTrue(validationResult.isValid);
assertEquals("+810476872055", validator.getNormalizedPhoneNumber());
// 03 Tokyo 03-XXXX-XXXX
validationResult = validator.validate("03-3129-5367");
assertTrue(validationResult.isValid);
assertEquals("+810331295367", validator.getNormalizedPhoneNumber());
// 090 Cell number (area code)
validationResult = validator.validate("(090) 3129-5367");
assertTrue(validationResult.isValid);
assertEquals("+8109031295367", validator.getNormalizedPhoneNumber());
}
@Test
public void testRussiaNumbers() {
validator = new PhoneNumberValidator("RU");
assertEquals(validator.getCallingCode(), "7");
// Moscow has four area codes: 495, 496, 498 and 499
validationResult = validator.validate("499 345-99-36");
assertTrue(validationResult.isValid);
assertEquals("+74993459936", validator.getNormalizedPhoneNumber());
// 812 St. Peter
validationResult = validator.validate("+7 812 567-22-11");
assertTrue(validationResult.isValid);
assertEquals("+78125672211", validator.getNormalizedPhoneNumber());
// 395 Irkutsk Oblast Call from outside RU
validationResult = validator.validate("+7 395 232-88-35");
assertTrue(validationResult.isValid);
assertEquals("+73952328835", validator.getNormalizedPhoneNumber());
}
@Test
public void testUKNumber() {
validator = new PhoneNumberValidator("GB");
assertEquals(validator.getCallingCode(), "44");
validationResult = validator.validate("020 7946 0230");
assertTrue(validationResult.isValid);
assertEquals("+4402079460230", validator.getNormalizedPhoneNumber());
validationResult = validator.validate("+ 44 20 79 46 00 93");
assertTrue(validationResult.isValid);
assertEquals("+442079460093", validator.getNormalizedPhoneNumber());
// (0114) Sheffield
validationResult = validator.validate("(0114) 436 8888");
assertTrue(validationResult.isValid);
assertEquals("+4401144368888", validator.getNormalizedPhoneNumber());
validationResult = validator.validate("+44 11 44368888");
assertTrue(validationResult.isValid);
assertEquals("+441144368888", validator.getNormalizedPhoneNumber());
// (0131) xxx xxxx Edinburgh
validationResult = validator.validate("(0131) 267 1111");
assertTrue(validationResult.isValid);
assertEquals("+4401312671111", validator.getNormalizedPhoneNumber());
validationResult = validator.validate("131 267-1111");
assertTrue(validationResult.isValid);
assertEquals("+441312671111", validator.getNormalizedPhoneNumber());
}
@Test
public void testUSNumber() {
validator = new PhoneNumberValidator("US");
assertEquals(validator.getCallingCode(), "1");
validationResult = validator.validate("(800) 253 0000");
assertTrue(validationResult.isValid);
assertEquals("+18002530000", validator.getNormalizedPhoneNumber());
validationResult = validator.validate("+ 1 800 253-0000");
assertTrue(validationResult.isValid);
assertEquals("+18002530000", validator.getNormalizedPhoneNumber());
validationResult = validator.validate("8002530000");
assertTrue(validationResult.isValid);
assertEquals("+18002530000", validator.getNormalizedPhoneNumber());
}
@Test
public void testInvalidUSNumbers() {
validator = new PhoneNumberValidator("US");
validationResult = validator.validate("+1 512 GR8 0150");
assertFalse("+1 512 GR8 0150 should not be a valid number in US", validationResult.isValid);
assertEquals(Res.get("validation.phone.invalidCharacters", "+1 512 GR8 0150", "US", validator.getCallingCode()),
validationResult.errorMessage);
assertNull(validator.getNormalizedPhoneNumber());
validationResult = validator.validate("+1 212-3456-0150-9832");
assertFalse("+1 212-3456-0150-9832 should not be a valid number in US", validationResult.isValid);
assertEquals(Res.get("validation.phone.tooManyDigits", "+1 212-3456-0150-9832", "US", validator.getCallingCode()),
validationResult.errorMessage);
assertNull(validator.getNormalizedPhoneNumber());
}
@Test
public void testUSAreaCodeMatchesCallingCode() {
// These are not valid US numbers because these area codes
// do not exist, but validating all area codes on the globe
// is probably too expensive. We have to trust end users
// to input correct area/region codes.
validator = new PhoneNumberValidator("US");
assertEquals(validator.getCallingCode(), "1");
validationResult = validator.validate("1 (1) 253 0000");
assertTrue(validationResult.isValid);
assertEquals("+112530000", validator.getNormalizedPhoneNumber());
validationResult = validator.validate("1-120-253 0000");
assertTrue(validationResult.isValid);
assertEquals("+11202530000", validator.getNormalizedPhoneNumber());
validationResult = validator.validate("(120) 253 0000");
assertTrue(validationResult.isValid);
// TODO validator incorrectly treats input as if it were +1 (202) 53-0000
/// assertEquals("+1202530000", validator.getNormalizedPhoneNumber());
}
}

View file

@ -0,0 +1,72 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.desktop.util.validation;
import bisq.core.locale.CurrencyUtil;
import bisq.core.locale.Res;
import bisq.core.util.validation.RegexValidator;
import bisq.common.config.BaseCurrencyNetwork;
import bisq.common.config.Config;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class RegexValidatorTest {
@Before
public void setup() {
final BaseCurrencyNetwork baseCurrencyNetwork = Config.baseCurrencyNetwork();
final String currencyCode = baseCurrencyNetwork.getCurrencyCode();
Res.setBaseCurrencyCode(currencyCode);
Res.setBaseCurrencyName(baseCurrencyNetwork.getCurrencyName());
CurrencyUtil.setBaseCurrencyCode(currencyCode);
}
@Test
public void validate() throws Exception {
RegexValidator validator = new RegexValidator();
assertTrue(validator.validate("").isValid);
assertTrue(validator.validate(null).isValid);
assertTrue(validator.validate("123456789").isValid);
validator.setPattern("[a-z]*");
assertTrue(validator.validate("abcdefghijklmnopqrstuvwxyz").isValid);
assertTrue(validator.validate("").isValid);
assertTrue(validator.validate(null).isValid);
assertFalse(validator.validate("123").isValid); // invalid
assertFalse(validator.validate("ABC").isValid); // invalid
validator.setPattern("[a-z]+");
assertTrue(validator.validate("abcdefghijklmnopqrstuvwxyz").isValid);
assertFalse(validator.validate("123").isValid); // invalid
assertFalse(validator.validate("ABC").isValid); // invalid
assertFalse(validator.validate("").isValid); // invalid
assertFalse(validator.validate(null).isValid); // invalid
}
}

View file

@ -0,0 +1,35 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package org.bitcoinj.core;
import com.natpryce.makeiteasy.Instantiator;
import com.natpryce.makeiteasy.Property;
import static com.natpryce.makeiteasy.MakeItEasy.a;
import static com.natpryce.makeiteasy.MakeItEasy.make;
import static org.bitcoinj.core.Coin.valueOf;
public class CoinMaker {
public static final Property<Coin, Long> satoshis = new Property<>();
public static final Instantiator<Coin> Coin = lookup ->
valueOf(lookup.valueOf(satoshis, 100000000L));
public static final Coin oneBitcoin = make(a(Coin));
}