From eb2e1a96bfab112820a22cb3929be6fca2db21f3 Mon Sep 17 00:00:00 2001 From: Christoph Atteneder Date: Tue, 12 Feb 2019 12:35:33 +0100 Subject: [PATCH] Add utm parameters to bisq.network links to be able to track referral traffic from client --- .../java/bisq/desktop/main/MainViewModel.java | 1 + .../main/java/bisq/desktop/util/GUIUtil.java | 41 +++++++++- .../java/bisq/desktop/util/GUIUtilTest.java | 75 ++++++++++++++----- 3 files changed, 96 insertions(+), 21 deletions(-) diff --git a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java index ea375a77b95..777acf2e52b 100644 --- a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java @@ -178,6 +178,7 @@ public MainViewModel(BisqSetup bisqSetup, BalanceWithConfirmationTextField.setWalletService(btcWalletService); GUIUtil.setFeeService(feeService); + GUIUtil.setPreferences(preferences); setupHandlers(); bisqSetup.addBisqSetupCompleteListener(this); diff --git a/desktop/src/main/java/bisq/desktop/util/GUIUtil.java b/desktop/src/main/java/bisq/desktop/util/GUIUtil.java index 77335f54dd3..53ca7e37c6f 100644 --- a/desktop/src/main/java/bisq/desktop/util/GUIUtil.java +++ b/desktop/src/main/java/bisq/desktop/util/GUIUtil.java @@ -140,11 +140,16 @@ public class GUIUtil { public final static int AMOUNT_DECIMALS = 4; private static FeeService feeService; + private static Preferences preferences; public static void setFeeService(FeeService feeService) { GUIUtil.feeService = feeService; } + public static void setPreferences(Preferences preferences) { + GUIUtil.preferences = preferences; + } + public static double getScrollbarWidth(Node scrollablePane) { Node node = scrollablePane.lookup(".scroll-bar"); if (node instanceof ScrollBar) { @@ -586,22 +591,54 @@ public static void updateConfidence(TransactionConfidence confidence, Tooltip to public static void openWebPage(String target) { + + if (target.contains("bisq.network")) { + // add utm parameters + target = appendURI(target, "utm_source=desktop-client&utm_medium=in-app-link&utm_campaign=language_" + + preferences.getUserLanguage()); + } + String key = "warnOpenURLWhenTorEnabled"; if (DontShowAgainLookup.showAgain(key)) { + final String finalTarget = target; new Popup<>().information(Res.get("guiUtil.openWebBrowser.warning", target)) .actionButtonText(Res.get("guiUtil.openWebBrowser.doOpen")) .onAction(() -> { DontShowAgainLookup.dontShowAgain(key, true); - doOpenWebPage(target); + doOpenWebPage(finalTarget); }) .closeButtonText(Res.get("guiUtil.openWebBrowser.copyUrl")) - .onClose(() -> Utilities.copyToClipboard(target)) + .onClose(() -> Utilities.copyToClipboard(finalTarget)) .show(); } else { doOpenWebPage(target); } } + private static String appendURI(String uri, String appendQuery) { + try { + final URI oldURI = new URI(uri); + + String newQuery = oldURI.getQuery(); + + if (newQuery == null) { + newQuery = appendQuery; + } else { + newQuery += "&" + appendQuery; + } + + URI newURI = new URI(oldURI.getScheme(), oldURI.getAuthority(), oldURI.getPath(), + newQuery, oldURI.getFragment()); + + return newURI.toString(); + } catch (URISyntaxException e) { + e.printStackTrace(); + log.error(e.getMessage()); + + return uri; + } + } + private static void doOpenWebPage(String target) { try { Utilities.openURI(new URI(target)); diff --git a/desktop/src/test/java/bisq/desktop/util/GUIUtilTest.java b/desktop/src/test/java/bisq/desktop/util/GUIUtilTest.java index fd81cb82c41..381290e9a92 100644 --- a/desktop/src/test/java/bisq/desktop/util/GUIUtilTest.java +++ b/desktop/src/test/java/bisq/desktop/util/GUIUtilTest.java @@ -20,37 +20,51 @@ import bisq.core.locale.GlobalSettings; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; +import bisq.core.user.DontShowAgainLookup; +import bisq.core.user.Preferences; + +import bisq.common.util.Utilities; import javafx.util.StringConverter; +import java.net.URI; + import java.util.HashMap; import java.util.Locale; import java.util.Map; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; -import static bisq.desktop.maker.CurrencyListItemMakers.bitcoinItem; -import static bisq.desktop.maker.CurrencyListItemMakers.euroItem; -import static bisq.desktop.maker.CurrencyListItemMakers.numberOfTrades; -import static bisq.desktop.maker.PreferenceMakers.empty; import static bisq.desktop.maker.TradeCurrencyMakers.bitcoin; import static bisq.desktop.maker.TradeCurrencyMakers.euro; -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; + + + +import org.mockito.ArgumentCaptor; +@RunWith(PowerMockRunner.class) +@PrepareForTest({Utilities.class, Preferences.class}) +@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"}) 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"); } - // @Christoph: not sure if that was removed with intentions in the release branch. - // I leave it here commented out in case it happened due a merge mistake. - /* @Test public void testTradeCurrencyConverter() { Map offerCounts = new HashMap() {{ @@ -68,16 +82,39 @@ public void testTradeCurrencyConverter() { } @Test - public void testCurrencyListWithOffersConverter() { - Res.setBaseCurrencyCode("BTC"); - Res.setBaseCurrencyName("Bitcoin"); - StringConverter currencyListItemConverter = GUIUtil.getCurrencyListItemConverter(Res.get("shared.oneOffer"), - Res.get("shared.multipleOffers"), - empty); + public void testOpenURLWithCampaignParameters() throws Exception { + Preferences preferences = mock(Preferences.class); + DontShowAgainLookup.setPreferences(preferences); + GUIUtil.setPreferences(preferences); + when(preferences.showAgain("warnOpenURLWhenTorEnabled")).thenReturn(false); + when(preferences.getUserLanguage()).thenReturn("en"); - assertEquals("✦ Bitcoin (BTC) - 10 offers", currencyListItemConverter.toString(make(bitcoinItem.but(with(numberOfTrades, 10))))); - assertEquals("★ Euro (EUR) - 0 offers", currencyListItemConverter.toString(make(euroItem))); - assertEquals("★ Euro (EUR) - 1 offer", currencyListItemConverter.toString(make(euroItem.but(with(numberOfTrades, 1))))); + PowerMockito.mockStatic(Utilities.class); + ArgumentCaptor 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() throws Exception { + Preferences preferences = mock(Preferences.class); + DontShowAgainLookup.setPreferences(preferences); + GUIUtil.setPreferences(preferences); + when(preferences.showAgain("warnOpenURLWhenTorEnabled")).thenReturn(false); + + PowerMockito.mockStatic(Utilities.class); + ArgumentCaptor 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()); + } }