From c88b5bfcfa24d90219eb7de64f4727c523fb7b5b Mon Sep 17 00:00:00 2001
From: uhensler <none@none>
Date: Fri, 16 Jun 2017 09:33:28 +0200
Subject: [PATCH] OO-2825: Aviod automatic completion of some password fields

---
 .../admin/user/ChangeUserPasswordForm.java    |   2 +
 .../olat/admin/user/UserCreateController.java |   2 +
 .../form/flexible/elements/TextElement.java   |  16 ++-
 .../impl/elements/AbstractTextElement.java    |  44 ++++++--
 .../impl/elements/TextElementRenderer.java    |   4 +
 .../olat/course/nodes/tu/TUConfigForm.java    |   1 +
 .../ims/qti21/ui/QTI21AdminController.java    |   1 +
 .../modules/fo/ui/MessageEditController.java  |   1 +
 .../modules/fo/ui/NewPseudonymController.java |   1 +
 .../ui/EditOrganizerController.java           |   1 +
 .../OpenMeetingsConfigurationController.java  |   2 +-
 .../ui/ViteroConfigurationController.java     |   1 +
 .../org/olat/registration/PwChangeForm.java   |   2 +
 .../olat/registration/RegistrationForm2.java  |   5 +-
 .../ui/PaypalMasterAccountController.java     |   1 +
 .../shibboleth/ShibbolethMigrationForm.java   |   1 +
 .../org/olat/user/ChangePasswordForm.java     |   2 +
 .../elements/TextElementRendererTest.java     | 101 ++++++++++++++++++
 .../java/org/olat/test/AllTestsJunit4.java    |   1 +
 19 files changed, 174 insertions(+), 15 deletions(-)
 create mode 100644 src/test/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementRendererTest.java

diff --git a/src/main/java/org/olat/admin/user/ChangeUserPasswordForm.java b/src/main/java/org/olat/admin/user/ChangeUserPasswordForm.java
index fe6cefb0058..75a87b12aa1 100644
--- a/src/main/java/org/olat/admin/user/ChangeUserPasswordForm.java
+++ b/src/main/java/org/olat/admin/user/ChangeUserPasswordForm.java
@@ -105,7 +105,9 @@ public class ChangeUserPasswordForm extends FormBasicController {
 		username.setEnabled(false);		
 		
 		pass1 = uifactory.addPasswordElement("pass1", "form.password.new1", 255, "", formLayout);
+		pass1.setAutocomplete("new-password");
 		pass2 = uifactory.addPasswordElement("pass2", "form.password.new2", 255, "", formLayout);
+		pass2.setAutocomplete("new-password");
 		uifactory.addFormSubmitButton("submit", formLayout);
 	}
 
diff --git a/src/main/java/org/olat/admin/user/UserCreateController.java b/src/main/java/org/olat/admin/user/UserCreateController.java
index bcbd61b8abc..cbc1f8f2bdc 100644
--- a/src/main/java/org/olat/admin/user/UserCreateController.java
+++ b/src/main/java/org/olat/admin/user/UserCreateController.java
@@ -223,12 +223,14 @@ class NewUserForm extends FormBasicController {
 			psw1TextElement.setDisplaySize(30);
 			psw1TextElement.setVisible(showPasswordFields);
 			psw1TextElement.setElementCssClass("o_sel_id_password1");
+			psw1TextElement.setAutocomplete("new-password");
 
 			psw2TextElement = uifactory.addPasswordElement(PASSWORD_NEW2, "new.form.password.new2", 255, "", formLayout);
 			psw2TextElement.setMandatory(true);
 			psw2TextElement.setDisplaySize(30);		
 			psw2TextElement.setVisible(showPasswordFields);
 			psw2TextElement.setElementCssClass("o_sel_id_password2");
+			psw2TextElement.setAutocomplete("new-password");
 		}
 		
 		uifactory.addFormSubmitButton("save", "submit.save", formLayout);
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/elements/TextElement.java b/src/main/java/org/olat/core/gui/components/form/flexible/elements/TextElement.java
index 8350eab2987..41425120fc6 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/elements/TextElement.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/elements/TextElement.java
@@ -180,7 +180,21 @@ public interface TextElement extends FormItem{
 	 * @return true: has a placeholder text ; false: has no placeholder
 	 */
 	public boolean hasPlaceholder();
-
+	
+	/**
+	 * Set the autocomplete behavior of the TextElement. Default value is null
+	 * (is same behavior as "on"). To avoid the automatic completion of password
+	 * fields use "new-password".
+	 * 
+	 * @param autocomplete
+	 */
+	public void setAutocomplete(String autocomplete);
+	
+	/**
+	 * 
+	 * @return the autocomplete value or null if not set
+	 */
+	public String getAutocomplete();
 
 	public void setDomReplacementWrapperRequired(boolean required);
 	
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/AbstractTextElement.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/AbstractTextElement.java
index 97bc0cdad4d..a3a7be878bf 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/AbstractTextElement.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/AbstractTextElement.java
@@ -84,6 +84,7 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 	private String checkRegexp;
 	private String checkRegexpErrorKey;
 	private String placeholder;
+	private String autocomplete;
 	private ItemValidatorProvider itemValidatorProvider;
 	protected boolean originalInitialised=false;
 	
@@ -145,6 +146,7 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 	/**
 	 * @see org.olat.core.gui.components.form.flexible.elements.TextElement#preventValueTrim()
 	 */
+	@Override
 	public void preventValueTrim(boolean preventTrim){
 		this.preventTrim = preventTrim;
 	}
@@ -154,6 +156,7 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 	 * 
 	 * @param value The value to set
 	 */
+	@Override
 	public void setValue(String value) {
 		if (value == null) {
 			value = "";
@@ -187,6 +190,7 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 	 * 
 	 * @param value The new original value
 	 */
+	@Override
 	public void setNewOriginalValue(String value) {
 		if (value == null) value = "";
 		original = new String(value);
@@ -200,6 +204,7 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 	 * 
 	 * @see org.olat.core.gui.components.form.flexible.elements.TextElement#setDisplaySize(int)
 	 */
+	@Override
 	public void setDisplaySize(int displaySize){
 		this.displaySize = displaySize;
 	}
@@ -212,10 +217,12 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 	/**
 	 * @see org.olat.core.gui.components.form.flexible.elements.TextElement#setMaxLength(int)
 	 */
+	@Override
 	public void setMaxLength(int maxLength){
 		this.maxlength = maxLength;
 	}
 
+	@Override
 	public void setCheckVisibleLength(boolean checkVisibleLength) {
 		this.checkVisibleLength = checkVisibleLength;
 	}
@@ -224,6 +231,7 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 	 * @param errorKey
 	 * @return
 	 */
+	@Override
 	public void setNotEmptyCheck(String errorKey) {
 		checkForNotEmpty = true;
 		notEmptyErrorKey = errorKey;
@@ -233,10 +241,9 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 		if (value == null || value.equals("")) {
 			setErrorKey(notEmptyErrorKey, null);
 			return false;
-		} else {
-			clearError();
-			return true;
 		}
+		clearError();
+		return true;
 	}
 	
 
@@ -247,6 +254,7 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 	 * @see org.olat.core.gui.components.form.flexible.elements.TextElement#setNotLongerThanCheck(int,
 	 *      java.lang.String)
 	 */
+	@Override
 	public void setNotLongerThanCheck(int maxLength, String errorKey) {
 		if (maxLength == -1) {
 			checkForLength = false;
@@ -286,6 +294,7 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 	 * @param errorKey
 	 * @return true if they are equal
 	 */
+	@Override
 	public void setIsEqualCheck(String otherValue, String errorKey) {
 		checkForEquals = true;
 		checkForOtherValue = otherValue;
@@ -296,9 +305,8 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 		if (value == null || !value.equals(checkForOtherValue)) {
 			setErrorKey(otherValueErrorKey, null);
 			return false;
-		} else {
-			return true;
 		}
+		return true;
 	}
 
 	/**
@@ -306,6 +314,7 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 	 * 
 	 * @return boolean true if is empty, false otherwhise
 	 */
+	@Override
 	public boolean isEmpty() {
 		return value.equals("");
 	}
@@ -316,6 +325,7 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 	 * @param errorKey
 	 * @return boolean true if is empty, false otherwise
 	 */
+	@Override
 	public boolean isEmpty(String errorKey) {
 		if (isEmpty()) {
 			setErrorKey(errorKey, null);
@@ -352,13 +362,26 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 		return (placeholder != null);
 	}
 	
-
+	@Override
+	public void setAutocomplete(String autocomplete) {
+		if (StringHelper.containsNonWhitespace(autocomplete)) {
+			this.autocomplete = autocomplete;
+		} else {
+			this.autocomplete = null;
+		}
+	}
 	
+	@Override
+	public String getAutocomplete() {
+		return autocomplete;
+	}
+
 	/**
 	 * @param regExp
 	 * @param errorKey
 	 * @return
 	 */
+	@Override
 	public void setRegexMatchCheck(String regExp, String errorKey) {
 		checkForMatchRegexp = true;
 		checkRegexp = regExp;
@@ -369,11 +392,11 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 		if (value == null || !value.matches(checkRegexp)) {
 			setErrorKey(checkRegexpErrorKey, null);
 			return false;
-		} else {
-			return true;
 		}
+		return true;
 	}
 	
+	@Override
 	public void setItemValidatorProvider(ItemValidatorProvider itemValidatorProvider){
 		checkForCustomItemValidator = (itemValidatorProvider != null);
 		this.itemValidatorProvider = itemValidatorProvider;
@@ -385,9 +408,8 @@ public abstract class AbstractTextElement extends FormItemImpl implements TextEl
 		boolean isValid = itemValidatorProvider.isValidValue(value, validationErrorCallback, locale);
 		if (isValid) {
 			return true;
-		} else {
-			setErrorKey(validationErrorCallback.getErrorKey(), validationErrorCallback.getArgs());
-			return false; 
 		}
+		setErrorKey(validationErrorCallback.getErrorKey(), validationErrorCallback.getArgs());
+		return false;
 	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementRenderer.java
index 9522a77b3f1..93ff5412520 100644
--- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementRenderer.java
@@ -87,6 +87,10 @@ class TextElementRenderer extends DefaultComponentRenderer {
 				sb.append(" autofocus");
 			}
 			
+			if (te.getAutocomplete() != null) {
+				sb.append(" autocomplete=\"").append(te.getAutocomplete()).append("\"");
+			}
+			
 			sb.append(" />");
 			
 			//add set dirty form only if enabled
diff --git a/src/main/java/org/olat/course/nodes/tu/TUConfigForm.java b/src/main/java/org/olat/course/nodes/tu/TUConfigForm.java
index f917bc04f7f..0b03d779c82 100644
--- a/src/main/java/org/olat/course/nodes/tu/TUConfigForm.java
+++ b/src/main/java/org/olat/course/nodes/tu/TUConfigForm.java
@@ -292,6 +292,7 @@ public class TUConfigForm extends FormBasicController {
 		
 		tuser = uifactory.addTextElement("user", "TUConfigForm.user", 255, user == null ? "" : user, formLayout);
 		tpass = uifactory.addPasswordElement("pass", "TUConfigForm.pass", 255, pass == null ? "" : pass, formLayout);
+		tpass.setAutocomplete("new-password");
 		
 		uifactory.addFormSubmitButton("submit", formLayout);
 		
diff --git a/src/main/java/org/olat/ims/qti21/ui/QTI21AdminController.java b/src/main/java/org/olat/ims/qti21/ui/QTI21AdminController.java
index 87124c2d22e..390a6808043 100644
--- a/src/main/java/org/olat/ims/qti21/ui/QTI21AdminController.java
+++ b/src/main/java/org/olat/ims/qti21/ui/QTI21AdminController.java
@@ -102,6 +102,7 @@ public class QTI21AdminController extends FormBasicController {
 		String password = StringHelper.containsNonWhitespace(certificatePassword) ? PASSWORD_PLACEHOLDER : "";
 		certificatePasswordEl = uifactory.addPasswordElement("digital.signature.certificate.password", "digital.signature.certificate.password",
 				256, password, layoutCont);
+		certificatePasswordEl.setAutocomplete("new-password");
 
 		mathExtensionEl = uifactory.addCheckboxesHorizontal("math.extension", "math.extension", layoutCont,
 				onKeys, onValues);
diff --git a/src/main/java/org/olat/modules/fo/ui/MessageEditController.java b/src/main/java/org/olat/modules/fo/ui/MessageEditController.java
index cc99e535684..6e34e26efc3 100644
--- a/src/main/java/org/olat/modules/fo/ui/MessageEditController.java
+++ b/src/main/java/org/olat/modules/fo/ui/MessageEditController.java
@@ -206,6 +206,7 @@ public class MessageEditController extends FormBasicController {
 			passwordEl = uifactory.addPasswordElement("password", "password", 128, "", formLayout);
 			passwordEl.setElementCssClass("o_sel_forum_message_alias_pass");
 			passwordEl.setPlaceholderKey("password.placeholder", null);
+			passwordEl.setAutocomplete("new-password");
 
 			if(guestOnly) {
 				usePseudonymEl.setVisible(false);
diff --git a/src/main/java/org/olat/modules/fo/ui/NewPseudonymController.java b/src/main/java/org/olat/modules/fo/ui/NewPseudonymController.java
index 5d35894f475..0f87d38c16e 100644
--- a/src/main/java/org/olat/modules/fo/ui/NewPseudonymController.java
+++ b/src/main/java/org/olat/modules/fo/ui/NewPseudonymController.java
@@ -67,6 +67,7 @@ public class NewPseudonymController extends FormBasicController {
 		
 		passwordEl = uifactory.addPasswordElement("password", "new.password.label", 128, "", formLayout);
 		passwordEl.setElementCssClass("o_sel_forum_alias_pass");
+		passwordEl.setAutocomplete("new-password");
 		
 		FormLayoutContainer buttonsCont = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
 		buttonsCont.setRootForm(mainForm);
diff --git a/src/main/java/org/olat/modules/gotomeeting/ui/EditOrganizerController.java b/src/main/java/org/olat/modules/gotomeeting/ui/EditOrganizerController.java
index 0cc73dc15df..cf54b3a3079 100644
--- a/src/main/java/org/olat/modules/gotomeeting/ui/EditOrganizerController.java
+++ b/src/main/java/org/olat/modules/gotomeeting/ui/EditOrganizerController.java
@@ -79,6 +79,7 @@ public class EditOrganizerController extends FormBasicController {
 		String username = organizer == null ? "" : organizer.getUsername();
 		usernameEl = uifactory.addTextElement("organizer.username", "organizer.username", 128, username, formLayout);
 		passwordEl = uifactory.addPasswordElement("organizer.password", "organizer.password", 128, "", formLayout);
+		passwordEl.setAutocomplete("new-password");
 		
 		FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
 		formLayout.add("buttons", buttonLayout);
diff --git a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsConfigurationController.java b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsConfigurationController.java
index 1a78268d7a4..a1b46dc60b3 100644
--- a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsConfigurationController.java
+++ b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsConfigurationController.java
@@ -98,7 +98,7 @@ public class OpenMeetingsConfigurationController extends FormBasicController {
 			loginEl = uifactory.addTextElement("openmeetings-login", "option.adminlogin", 32, login, moduleFlc);
 			String password = openMeetingsModule.getAdminPassword();
 			passwordEl = uifactory.addPasswordElement("openmeetings-password", "option.adminpassword", 32, password, moduleFlc);
-			
+			passwordEl.setAutocomplete("new-password");
 			
 			String externalType = openMeetingsManager.getOpenOLATExternalType();
 			uifactory.addStaticTextElement("om.externaltype", "openolat.externaltype", externalType, moduleFlc);
diff --git a/src/main/java/org/olat/modules/vitero/ui/ViteroConfigurationController.java b/src/main/java/org/olat/modules/vitero/ui/ViteroConfigurationController.java
index e9ef7d3da0d..09589579f89 100644
--- a/src/main/java/org/olat/modules/vitero/ui/ViteroConfigurationController.java
+++ b/src/main/java/org/olat/modules/vitero/ui/ViteroConfigurationController.java
@@ -123,6 +123,7 @@ public class ViteroConfigurationController extends FormBasicController {
 			loginEl = uifactory.addTextElement("vitero-login", "option.adminlogin", 32, login, moduleFlc);
 			String password = viteroModule.getAdminPassword();
 			passwordEl = uifactory.addPasswordElement("vitero-password", "option.adminpassword", 32, password, moduleFlc);
+			passwordEl.setAutocomplete("new-password");
 			int customerId = viteroModule.getCustomerId();
 			String customer = customerId > 0 ? Integer.toString(customerId) : null;
 			customerEl = uifactory.addTextElement("option.customerId", "option.customerId", 32, customer, moduleFlc);
diff --git a/src/main/java/org/olat/registration/PwChangeForm.java b/src/main/java/org/olat/registration/PwChangeForm.java
index 80f76dbb424..33c7c6c0b25 100644
--- a/src/main/java/org/olat/registration/PwChangeForm.java
+++ b/src/main/java/org/olat/registration/PwChangeForm.java
@@ -135,7 +135,9 @@ public class PwChangeForm extends FormBasicController {
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
 		setFormTitle("form.password.enter.new");
 		newpass1 = uifactory.addPasswordElement("newpass1",  "form.password.new1", 128, "", formLayout);
+		newpass1.setAutocomplete("new-password");
 		newpass2 = uifactory.addPasswordElement("newpass2",  "form.password.new2", 128, "", formLayout);
+		newpass2.setAutocomplete("new-password");
 		uifactory.addFormSubmitButton("submit", formLayout);
 	}
 
diff --git a/src/main/java/org/olat/registration/RegistrationForm2.java b/src/main/java/org/olat/registration/RegistrationForm2.java
index c317c2fd5d7..f4fed839d77 100644
--- a/src/main/java/org/olat/registration/RegistrationForm2.java
+++ b/src/main/java/org/olat/registration/RegistrationForm2.java
@@ -198,10 +198,11 @@ public class RegistrationForm2 extends FormBasicController {
 		}
 		
 		newpass1 = uifactory.addPasswordElement("newpass1",  "form.password.new1", 128, "", formLayout);
-		newpass2 = uifactory.addPasswordElement("newpass2",  "form.password.new2", 128, "", formLayout);
-
 		newpass1.setMandatory(true);
+		newpass1.setAutocomplete("new-password");
+		newpass2 = uifactory.addPasswordElement("newpass2",  "form.password.new2", 128, "", formLayout);
 		newpass2.setMandatory(true);
+		newpass2.setAutocomplete("new-password");
 	
 		// Button layout
 		buttonLayout = FormLayoutContainer.createButtonLayout("button_layout", getTranslator());
diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/paypal/ui/PaypalMasterAccountController.java b/src/main/java/org/olat/resource/accesscontrol/provider/paypal/ui/PaypalMasterAccountController.java
index 9c0e6e16e1f..0a8579af277 100644
--- a/src/main/java/org/olat/resource/accesscontrol/provider/paypal/ui/PaypalMasterAccountController.java
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/paypal/ui/PaypalMasterAccountController.java
@@ -155,6 +155,7 @@ public class PaypalMasterAccountController extends FormBasicController {
 			usernameEl = uifactory.addTextElement("api-username", "paypal.config.username", 255, userId, formLayout);
 			passwordEl = uifactory.addPasswordElement("api-password", "paypal.config.password", 255, "", formLayout);
 			passwordEl.setExampleKey("paypal.config.password.expl", null);
+			passwordEl.setAutocomplete("new-password");
 			String signature = paypalModule.getPaypalSecuritySignature();
 			signatureEl = uifactory.addTextElement("api-signature", "paypal.config.signature", 255, signature, formLayout);
 			String applicationId = paypalModule.getPaypalApplicationId();
diff --git a/src/main/java/org/olat/shibboleth/ShibbolethMigrationForm.java b/src/main/java/org/olat/shibboleth/ShibbolethMigrationForm.java
index 43a5de2aeed..a760a1581e4 100644
--- a/src/main/java/org/olat/shibboleth/ShibbolethMigrationForm.java
+++ b/src/main/java/org/olat/shibboleth/ShibbolethMigrationForm.java
@@ -107,6 +107,7 @@ public class ShibbolethMigrationForm extends FormBasicController {
 		login.setEnabled(false);
 		
 		password = uifactory.addPasswordElement("smf_password", "smf.password", 255, "", formLayout);
+		password.setAutocomplete("new-password");
 		
 		FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("button_layout", getTranslator());
 		formLayout.add(buttonLayout);
diff --git a/src/main/java/org/olat/user/ChangePasswordForm.java b/src/main/java/org/olat/user/ChangePasswordForm.java
index dc58b60d55d..ae5e91417a4 100644
--- a/src/main/java/org/olat/user/ChangePasswordForm.java
+++ b/src/main/java/org/olat/user/ChangePasswordForm.java
@@ -114,8 +114,10 @@ public class ChangePasswordForm extends FormBasicController {
 		oldpass.setElementCssClass("o_sel_home_pwd_old");
 		newpass1 = uifactory.addPasswordElement("newpass1",  "form.password.new1", 128, "", formLayout);
 		newpass1.setElementCssClass("o_sel_home_pwd_new_1");
+		newpass1.setAutocomplete("new-password");
 		newpass2 = uifactory.addPasswordElement("newpass2",  "form.password.new2", 128, "", formLayout);
 		newpass2.setElementCssClass("o_sel_home_pwd_new_2");
+		newpass2.setAutocomplete("new-password");
 		
 		// Button layout
 		FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("button_layout", getTranslator());
diff --git a/src/test/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementRendererTest.java b/src/test/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementRendererTest.java
new file mode 100644
index 00000000000..da38fc4c11d
--- /dev/null
+++ b/src/test/java/org/olat/core/gui/components/form/flexible/impl/elements/TextElementRendererTest.java
@@ -0,0 +1,101 @@
+/**
+ * <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.core.gui.components.form.flexible.impl.elements;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.olat.core.gui.components.form.flexible.impl.Form;
+import org.olat.core.gui.render.StringOutput;
+
+/**
+ * 
+ * Initial date: 12.06.2017<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class TextElementRendererTest {
+	
+	private static String AUTOCOMPLETE = "autocomplete";
+	private static String AUTOCOMPLETE_NONE = "none";
+	private static boolean ENABLED = true;
+	private static boolean DISABLED = false;
+
+	private TextElementComponent textElementComponentMock;
+	private TextElementImpl textElementImplMock;
+	private Form formMock;
+	private StringOutput stringOutput;
+	private TextElementRenderer sut;
+	
+	@Before
+	public void setup() {
+		formMock = mock(Form.class);
+		textElementComponentMock = mock(TextElementComponent.class);
+		textElementImplMock = mock(TextElementImpl.class);
+		stringOutput = new StringOutput();
+		sut = new TextElementRenderer();
+	}
+
+	@Test
+	public void renderShouldAppendAutocompleteIfSet() {
+		when(textElementImplMock.getRootForm()).thenReturn(formMock);
+		when(textElementImplMock.getAutocomplete()).thenReturn(AUTOCOMPLETE_NONE);
+		when(textElementComponentMock.isEnabled()).thenReturn(ENABLED);
+		when(textElementComponentMock.getTextElementImpl()).thenReturn(textElementImplMock);
+		
+		sut.render(null, stringOutput, textElementComponentMock, null, null, null, null);
+
+		String autocompleteHtml = new StringBuilder()
+				.append(AUTOCOMPLETE)
+				.append("=\"")
+				.append(AUTOCOMPLETE_NONE)
+				.append("\"")
+				.toString();
+		assertThat(stringOutput.toString()).containsIgnoringCase(autocompleteHtml);
+	}
+	
+	@Test
+	public void renderShouldNotPringAutocompleteIfNull() {
+		when(textElementImplMock.getRootForm()).thenReturn(formMock);
+		when(textElementImplMock.isEnabled()).thenReturn(ENABLED);
+		when(textElementImplMock.getAutocomplete()).thenReturn(null);
+		when(textElementComponentMock.getTextElementImpl()).thenReturn(textElementImplMock);
+		
+		sut.render(null, stringOutput, textElementComponentMock, null, null, null, null);
+
+		assertThat(stringOutput.toString()).doesNotContain(AUTOCOMPLETE);
+	}
+	
+	@Test
+	public void renderShouldNotPringAutocompleteIfNotEnabled() {
+		when(textElementImplMock.getRootForm()).thenReturn(formMock);
+		when(textElementImplMock.isEnabled()).thenReturn(DISABLED);
+		when(textElementImplMock.getAutocomplete()).thenReturn(AUTOCOMPLETE_NONE);
+		when(textElementComponentMock.getTextElementImpl()).thenReturn(textElementImplMock);
+		
+		sut.render(null, stringOutput, textElementComponentMock, null, null, null, null);
+
+		assertThat(stringOutput.toString()).doesNotContain(AUTOCOMPLETE);
+	}
+	
+}
diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java
index 24491434053..705de8e5b6b 100644
--- a/src/test/java/org/olat/test/AllTestsJunit4.java
+++ b/src/test/java/org/olat/test/AllTestsJunit4.java
@@ -309,6 +309,7 @@ import org.junit.runners.Suite;
 	/**
 	 * Pure JUnit test without need of framework
 	 */
+	org.olat.core.gui.components.form.flexible.impl.elements.TextElementRendererTest.class,
 	org.olat.modules.card2brain.manager.Card2BrainManagerImplTest.class,
 	org.olat.modules.fo.WordCountTest.class,
 	org.olat.modules.webFeed.manager.FeedManagerImplTest.class,
-- 
GitLab