From 049eee43e14c20c80f860b908aa6ddc6e99f33e7 Mon Sep 17 00:00:00 2001
From: srosse <stephane.rosse@frentix.com>
Date: Mon, 11 Jan 2021 16:11:48 +0100
Subject: [PATCH] OO-5200: optimise selection of buyer's country

---
 .../paypalcheckout/PaypalCheckoutManager.java |  4 +
 .../paypalcheckout/PaypalCheckoutModule.java  | 26 +++++
 .../manager/PaypalCheckoutManagerImpl.java    | 49 ++++++++++
 ...heckoutAccountConfigurationController.java | 49 ++++++++++
 .../ui/PaypalSmartButtonAccessController.java |  6 ++
 .../ui/_content/paypal_smart_buttons.html     |  2 +-
 .../ui/_i18n/LocalStrings_de.properties       |  2 +
 .../ui/_i18n/LocalStrings_en.properties       |  2 +
 .../manager/PaypalCheckoutManagerTest.java    | 97 +++++++++++++++++++
 .../java/org/olat/test/AllTestsJunit4.java    |  1 +
 10 files changed, 237 insertions(+), 1 deletion(-)
 create mode 100644 src/test/java/org/olat/resource/accesscontrol/provider/paypalcheckout/manager/PaypalCheckoutManagerTest.java

diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/PaypalCheckoutManager.java b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/PaypalCheckoutManager.java
index 1f30465bb0b..c706ce81f55 100644
--- a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/PaypalCheckoutManager.java
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/PaypalCheckoutManager.java
@@ -20,6 +20,7 @@
 package org.olat.resource.accesscontrol.provider.paypalcheckout;
 
 import java.util.List;
+import java.util.Locale;
 
 import org.olat.core.id.Identity;
 import org.olat.resource.accesscontrol.OfferAccess;
@@ -91,4 +92,7 @@ public interface PaypalCheckoutManager {
 	
 	public List<PaypalCheckoutTransaction> searchTransactions(String id);
 	
+	
+	public String getPreferredLocale(Locale locale);
+	
 }
diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/PaypalCheckoutModule.java b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/PaypalCheckoutModule.java
index 2a3dbb85271..5017ed8d8bc 100644
--- a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/PaypalCheckoutModule.java
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/PaypalCheckoutModule.java
@@ -51,6 +51,7 @@ public class PaypalCheckoutModule extends AbstractSpringModule {
 	private static final String PAYPAL_SMART_BUTTONS = "paypal.checkout.v2.smart.buttons";
 	private static final String PAYPAL_WEBHOOK_ID = "paypal.webhhok.id";
 	private static final String PAYPAL_ACCEPT_PENDING_REVIEW = "paypal.checkout.v2.accept.pending.review";
+	private static final String PAYPAL_PREFERRED_COUNTRIES = "paypal.preferRed.countries";
 	
 	private static final String[] currencies = new String[] {
 			"AUD",
@@ -93,6 +94,8 @@ public class PaypalCheckoutModule extends AbstractSpringModule {
 	private boolean acceptPendingReview;
 	@Value("${paypal.webhhok.id:#{null}}")
 	private String webhookId;
+	@Value("${paypal.preferred.countries:CH}")
+	private String preferredCountries;
 	
 	@Autowired
 	private PaypalRESTWebhookProvider webhookProvider;
@@ -193,6 +196,29 @@ public class PaypalCheckoutModule extends AbstractSpringModule {
 		setStringProperty(PAYPAL_ACCEPT_PENDING_REVIEW, Boolean.toString(accept), true);
 	}
 	
+	/**
+	 * @return An immutable list of countries to prefer
+	 */
+	public List<String> getPreferredCountriesList() {
+		List<String> countries;
+		if(StringHelper.containsNonWhitespace(preferredCountries)) {
+			String[] countriesArr = preferredCountries.split("[,]");
+			countries = List.of(countriesArr);
+		} else {
+			countries = List.of();
+		}
+		return countries;
+	}
+	
+	public String getPreferredCountries() {
+		return preferredCountries;
+	}
+
+	public void setPreferredCountries(String preferredCountries) {
+		this.preferredCountries = preferredCountries;
+		setStringProperty(PAYPAL_PREFERRED_COUNTRIES, preferredCountries, true);
+	}
+
 	public String getExcludeFundings() {
 		return excludeFundings;
 	}
diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/manager/PaypalCheckoutManagerImpl.java b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/manager/PaypalCheckoutManagerImpl.java
index 973bbf27d3e..0ea954fabe0 100644
--- a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/manager/PaypalCheckoutManagerImpl.java
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/manager/PaypalCheckoutManagerImpl.java
@@ -22,12 +22,15 @@ package org.olat.resource.accesscontrol.provider.paypalcheckout.manager;
 import java.io.IOException;
 import java.util.Date;
 import java.util.List;
+import java.util.Locale;
 
 import org.apache.logging.log4j.Logger;
 import org.olat.core.commons.persistence.DB;
 import org.olat.core.helpers.Settings;
 import org.olat.core.id.Identity;
 import org.olat.core.logging.Tracing;
+import org.olat.core.util.StringHelper;
+import org.olat.core.util.i18n.I18nManager;
 import org.olat.resource.OLATResource;
 import org.olat.resource.accesscontrol.ACService;
 import org.olat.resource.accesscontrol.AccessTransaction;
@@ -74,6 +77,8 @@ public class PaypalCheckoutManagerImpl implements PaypalCheckoutManager {
 	@Autowired
 	private ACOrderDAO orderManager;
 	@Autowired
+	private I18nManager i18nManager;
+	@Autowired
 	private ACReservationDAO reservationDao;
 	@Autowired
 	private CheckoutV2Provider checkoutProvider;
@@ -84,6 +89,50 @@ public class PaypalCheckoutManagerImpl implements PaypalCheckoutManager {
 	@Autowired
 	private PaypalCheckoutTransactionDAO transactionDao;
 	
+
+	@Override
+	public String getPreferredLocale(Locale locale) {
+		String val;
+		List<String> preferredCountries = checkoutModule.getPreferredCountriesList();
+		if(preferredCountries.isEmpty()) {
+			Locale regionalizedLocale = i18nManager.getRegionalizedLocale(locale);
+			val = regionalizedLocale.toString();
+		} else {
+			String language = locale.getLanguage();
+			String country = locale.getCountry();
+			if(!StringHelper.containsNonWhitespace(country)) {
+				Locale[] allLocales = Locale.getAvailableLocales();
+				for(String preferredCountry:preferredCountries) {
+					if(exists(language, preferredCountry, allLocales)) {
+						country = preferredCountry;
+						break;
+					}
+				}
+			}
+
+			if(StringHelper.containsNonWhitespace(country)) {
+				val = language + "_" + country.toUpperCase();
+			} else {
+				Locale regionalizedLocale = i18nManager.getRegionalizedLocale(locale);
+				val = regionalizedLocale.toString();
+			}
+		}
+		
+		if(!StringHelper.containsNonWhitespace(val)) {
+			val = "de_CH";
+		}
+		return val;
+	}
+	
+	private boolean exists(String language, String country, Locale[] allLocales) {
+		for(Locale locale:allLocales) {
+			if(locale.getCountry().equals(country) && locale.getLanguage().equals(language)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
 	@Override
 	public CheckoutRequest request(Identity delivery, OfferAccess offerAccess, String mapperUri, String sessionId) {
 		StringBuilder url = new StringBuilder();
diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/PaypalCheckoutAccountConfigurationController.java b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/PaypalCheckoutAccountConfigurationController.java
index b419a76f3c1..d9643007ab8 100644
--- a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/PaypalCheckoutAccountConfigurationController.java
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/PaypalCheckoutAccountConfigurationController.java
@@ -19,7 +19,10 @@
  */
 package org.olat.resource.accesscontrol.provider.paypalcheckout.ui;
 
+import java.text.Collator;
+import java.util.Collection;
 import java.util.List;
+import java.util.Locale;
 
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.form.flexible.FormItem;
@@ -34,6 +37,7 @@ import org.olat.core.gui.components.util.KeyValues;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.util.StringHelper;
+import org.olat.core.util.i18n.I18nModule;
 import org.olat.resource.accesscontrol.AccessControlModule;
 import org.olat.resource.accesscontrol.provider.paypalcheckout.PaypalCheckoutModule;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -56,9 +60,12 @@ public class PaypalCheckoutAccountConfigurationController extends FormBasicContr
 	private SingleSelection smartButtonsEl;
 	private MultipleSelectionElement enableEl;
 	private MultipleSelectionElement pendingReviewEl;
+	private MultipleSelectionElement preferredCountriesEl;
 	
 	private final List<String> paypalCurrencies;
 
+	@Autowired
+	private I18nModule i18nModule;
 	@Autowired
 	private AccessControlModule acModule;
 	@Autowired
@@ -111,6 +118,17 @@ public class PaypalCheckoutAccountConfigurationController extends FormBasicContr
 			currencyEl.select("CHF", true);
 		}
 		
+		KeyValues countries = getCountries();
+		preferredCountriesEl = uifactory.addCheckboxesDropdown("countries", "paypal.preferred.countries", formLayout,
+				countries.keys(), countries.values());
+		preferredCountriesEl.setHelpTextKey("paypal.preferred.countries.hint", null);
+		List<String> preferredCountries = paypalModule.getPreferredCountriesList();
+		for(String country:preferredCountries) {
+			if(countries.containsKey(country)) {
+				preferredCountriesEl.select(country, true);
+			}
+		}
+		
 		String clientId = paypalModule.getClientId();
 		clientIdEl = uifactory.addTextElement("checkout.client.id", 128, clientId, formLayout);
 		String clientSecret = paypalModule.getClientSecret();
@@ -121,6 +139,27 @@ public class PaypalCheckoutAccountConfigurationController extends FormBasicContr
 		uifactory.addFormSubmitButton("save", buttonGroupLayout);
 	}
 	
+	private KeyValues getCountries() {
+		KeyValues keyValues = new KeyValues();
+		Collection<Locale> languages = i18nModule.getAllLocales().values();
+		Locale[] locales = Locale.getAvailableLocales();
+		for(Locale language:languages) {
+			for(Locale locale:locales) {
+				if(language.getLanguage().equals(locale.getLanguage())) {
+					String country = locale.getCountry();
+					String displayCountry = locale.getDisplayCountry(getLocale());
+					if(!keyValues.containsKey(country) && StringHelper.containsNonWhitespace(displayCountry)) {
+						keyValues.add(KeyValues.entry(country, displayCountry));
+					}
+				}
+			}
+		}
+		
+		final Collator collator = Collator.getInstance(getLocale());
+		keyValues.sort((k1, k2) -> collator.compare(k1.getValue(), k2.getValue()));
+		return keyValues;
+	}
+	
 	private void updateUI() {
 		boolean enabled = enableEl.isAtLeastSelected(1);
 		currencyEl.setVisible(enabled);
@@ -164,6 +203,15 @@ public class PaypalCheckoutAccountConfigurationController extends FormBasicContr
 		}
 		super.formInnerEvent(ureq, source, event);
 	}
+	
+	private String getPreferredCountries() {
+		StringBuilder sb = new StringBuilder();
+		for(String country:preferredCountriesEl.getSelectedKeys()) {
+			if(sb.length() > 0) sb.append(",");
+			sb.append(country);
+		}
+		return sb.toString();
+	}
 
 	@Override
 	protected void formOK(UserRequest ureq) {
@@ -177,6 +225,7 @@ public class PaypalCheckoutAccountConfigurationController extends FormBasicContr
 			}
 			paypalModule.setSmartButtons(smartButtonsEl.isOneSelected() && smartButtonsEl.isSelected(0));
 			paypalModule.setAcceptPendingReview(pendingReviewEl.isAtLeastSelected(1));
+			paypalModule.setPreferredCountries(getPreferredCountries());
 			doUpdateWebhook();
 		} else {
 			paypalModule.setClientId(null);
diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/PaypalSmartButtonAccessController.java b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/PaypalSmartButtonAccessController.java
index 948ff7524da..e25ecf467e1 100644
--- a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/PaypalSmartButtonAccessController.java
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/PaypalSmartButtonAccessController.java
@@ -31,6 +31,7 @@ import org.olat.core.util.Formatter;
 import org.olat.core.util.StringHelper;
 import org.olat.resource.accesscontrol.OfferAccess;
 import org.olat.resource.accesscontrol.Price;
+import org.olat.resource.accesscontrol.provider.paypalcheckout.PaypalCheckoutManager;
 import org.olat.resource.accesscontrol.provider.paypalcheckout.PaypalCheckoutModule;
 import org.olat.resource.accesscontrol.ui.FormController;
 import org.olat.resource.accesscontrol.ui.PriceFormat;
@@ -48,6 +49,8 @@ public class PaypalSmartButtonAccessController extends FormBasicController imple
 	
 	@Autowired
 	private PaypalCheckoutModule paypalModule;
+	@Autowired
+	private PaypalCheckoutManager paypalCheckoutManager;
 	
 	public PaypalSmartButtonAccessController(UserRequest ureq, WindowControl wControl, OfferAccess link) {
 		super(ureq, wControl, "paypal_smart_buttons");
@@ -73,6 +76,9 @@ public class PaypalSmartButtonAccessController extends FormBasicController imple
 			layoutCont.contextPut("excludeFundings", excludeFundings == null ? "" : excludeFundings);
 			layoutCont.contextPut("csrfToken", ureq.getUserSession().getCsrfToken());
 			
+			String preferedLocale = paypalCheckoutManager.getPreferredLocale(getLocale());
+			layoutCont.contextPut("plocale", preferedLocale);
+			
 			String description = link.getOffer().getDescription();
 			if(StringHelper.containsNonWhitespace(description)) {
 				if(!StringHelper.isHtml(description)) {
diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/_content/paypal_smart_buttons.html b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/_content/paypal_smart_buttons.html
index 8fa7d7f612e..ce157276be4 100644
--- a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/_content/paypal_smart_buttons.html
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/_content/paypal_smart_buttons.html
@@ -21,7 +21,7 @@
 				<script defer data-csp-nonce="${csrfToken}">
 				jQuery(function() {
 					jQuery.ajax({
-						url: 'https://www.paypal.com/sdk/js?client-id=$clientId&currency=${currency}&intent=authorize&commit=true&disable-funding=${excludeFundings}',
+						url: 'https://www.paypal.com/sdk/js?client-id=$clientId&locale=$plocale&currency=${currency}&intent=authorize&commit=true&disable-funding=${excludeFundings}',
 						cache: true,//paypal don't like the anti-cache parameter
 						dataType: "script",
 						success: loadButtons,
diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/_i18n/LocalStrings_de.properties
index ee61ca10472..9b91cab3fbb 100644
--- a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/_i18n/LocalStrings_de.properties
@@ -40,6 +40,8 @@ paypal.order.status.reason=Status Erkl\u00E4rung
 paypal.pending.review=Ausstehende Transaktionen
 paypal.pending.review.accept=Defaultmessig akkzeptieren (Buchung zum Kurs wird durchgef\u00FChrt)
 paypal.pending.review.accept.explain=Stornieren von Transaktionen in PayPal werden nicht automatisch Mitgliedschaft im Kurs k\u00FCndigen.
+paypal.preferred.countries=Vorselektierte L\u00E4nder
+paypal.preferred.countries.hint=Probiert abhängig von der Benutzer Sprache den Land vorzuseleketieren
 paypal.process.transaction=Transaktion ist erfolgreich und wird verarbeitet.
 paypal.reservation.failed=Es gibt momentan keinen freien Platz.
 paypal.segment.account=Konto
diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/_i18n/LocalStrings_en.properties
index 7e23e44f325..c29b407af2d 100644
--- a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/_i18n/LocalStrings_en.properties
@@ -40,6 +40,8 @@ paypal.order.status.reason=Status reason
 paypal.pending.review=Pending transactions
 paypal.pending.review.accept=Accept per default (booking to course will be completed)
 paypal.pending.review.accept.explain=Canceling transactions in PayPal will not automatically cancel the membership to the course.
+paypal.preferred.countries=Preselected countries
+paypal.preferred.countries.hint=Try to pre-select the countries defined here depending of the language of the user.
 paypal.process.transaction=Your transaction is approved and is currently processed.
 paypal.reservation.failed=There isn't currently an available place.
 paypal.segment.account=Account
diff --git a/src/test/java/org/olat/resource/accesscontrol/provider/paypalcheckout/manager/PaypalCheckoutManagerTest.java b/src/test/java/org/olat/resource/accesscontrol/provider/paypalcheckout/manager/PaypalCheckoutManagerTest.java
new file mode 100644
index 00000000000..584d0cafb58
--- /dev/null
+++ b/src/test/java/org/olat/resource/accesscontrol/provider/paypalcheckout/manager/PaypalCheckoutManagerTest.java
@@ -0,0 +1,97 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.resource.accesscontrol.provider.paypalcheckout.manager;
+
+import java.util.Locale;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.olat.core.util.i18n.I18nManager;
+import org.olat.resource.accesscontrol.provider.paypalcheckout.PaypalCheckoutManager;
+import org.olat.resource.accesscontrol.provider.paypalcheckout.PaypalCheckoutModule;
+import org.olat.test.OlatTestCase;
+import org.springframework.beans.factory.annotation.Autowired;
+
+
+/**
+ * 
+ * Initial date: 11 janv. 2021<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class PaypalCheckoutManagerTest extends OlatTestCase {
+
+	@Autowired
+	private I18nManager i18nManager;
+	@Autowired
+	private PaypalCheckoutModule paypalCheckoutModule;
+	@Autowired
+	private PaypalCheckoutManager paypalCheckoutManager;
+	
+	@Test
+	public void preferredLocale() {
+		paypalCheckoutModule.setPreferredCountries("");
+		
+		Locale deLocale = i18nManager.getLocaleOrDefault("de");
+		String preferredDeLocale = paypalCheckoutManager.getPreferredLocale(deLocale);
+		Assert.assertEquals("de_DE", preferredDeLocale);
+		
+		Locale frLocale = i18nManager.getLocaleOrDefault("fr");
+		String preferredFrLocale = paypalCheckoutManager.getPreferredLocale(frLocale);
+		Assert.assertEquals("fr_FR", preferredFrLocale);
+		
+		Locale jpLocale = i18nManager.getLocaleOrDefault("jp");
+		String preferredJpLocale = paypalCheckoutManager.getPreferredLocale(jpLocale);
+		Assert.assertEquals("ja_JP", preferredJpLocale);
+		
+		Locale ptBrLocale = i18nManager.getLocaleOrDefault("pt_BR");
+		String preferredPtBrLocale = paypalCheckoutManager.getPreferredLocale(ptBrLocale);
+		Assert.assertEquals("pt_BR", preferredPtBrLocale);
+
+		Locale enLocale = i18nManager.getLocaleOrDefault("en");
+		String preferredEnLocale = paypalCheckoutManager.getPreferredLocale(enLocale);
+		Assert.assertTrue(preferredEnLocale.startsWith("en"));
+	}
+	
+	@Test
+	public void preferredLocaleInSwitzerland() {
+		paypalCheckoutModule.setPreferredCountries("CH");
+		
+		Locale deLocale = i18nManager.getLocaleOrDefault("de");
+		String preferredDeLocale = paypalCheckoutManager.getPreferredLocale(deLocale);
+		Assert.assertEquals("de_CH", preferredDeLocale);
+		
+		Locale frLocale = i18nManager.getLocaleOrDefault("fr");
+		String preferredFrLocale = paypalCheckoutManager.getPreferredLocale(frLocale);
+		Assert.assertEquals("fr_CH", preferredFrLocale);
+		
+		Locale jpLocale = i18nManager.getLocaleOrDefault("jp");
+		String preferredJpLocale = paypalCheckoutManager.getPreferredLocale(jpLocale);
+		Assert.assertEquals("ja_JP", preferredJpLocale);
+		
+		Locale ptBrLocale = i18nManager.getLocaleOrDefault("pt_BR");
+		String preferredPtBrLocale = paypalCheckoutManager.getPreferredLocale(ptBrLocale);
+		Assert.assertEquals("pt_BR", preferredPtBrLocale);
+
+		Locale enLocale = i18nManager.getLocaleOrDefault("en");
+		String preferredEnLocale = paypalCheckoutManager.getPreferredLocale(enLocale);
+		Assert.assertEquals("en_CH", preferredEnLocale);
+	}
+}
diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java
index 7d9c4e9c363..aa0681fa0b6 100644
--- a/src/test/java/org/olat/test/AllTestsJunit4.java
+++ b/src/test/java/org/olat/test/AllTestsJunit4.java
@@ -486,6 +486,7 @@ import org.junit.runners.Suite;
 	org.olat.resource.accesscontrol.ACReservationDAOTest.class,
 	org.olat.resource.accesscontrol.provider.auto.AutoAccessManagerTest.class,
 	org.olat.resource.accesscontrol.provider.auto.manager.AdvanceOrderDAOTest.class,
+	org.olat.resource.accesscontrol.provider.paypalcheckout.manager.PaypalCheckoutManagerTest.class,
 	org.olat.resource.accesscontrol.provider.paypalcheckout.manager.PaypalCheckoutTransactionDAOTest.class,
 	/**
 	 * Pure JUnit test without need of framework
-- 
GitLab