Why #Constraints annotation are not working on my tests? - java

I've created this User class:
#Entity
public class User extends Model {
#Id
#Constraints.Email
public String email;
#Constraints.MinLength(3)
#Constraints.MaxLength(255)
public String firstName;
#Constraints.MinLength(3)
#Constraints.MaxLength(255)
public String lastName;
#Constraints.MinLength(3)
#Constraints.MaxLength(255)
public String username;
#Constraints.MinLength(16)
#Constraints.MaxLength(255)
public String password;
public static Finder<String, User> finder = new Finder<>(User.class);
public static User create(User user){
user.password = BCrypt.hashpw(user.password, BCrypt.gensalt(12));
user.save();
return user;
}
...
}
And I noticed that I can save an empty User. Which means, with no email, nothing, this User will be persisted on my database.
#Test
public void createEmptyUser(){
User user = new User();
user.email="";
user.save();
assertTrue(user.email.isEmpty());
assertNotNull(User.finder.byId(user.email));
assertEquals(true, User.findByEmail(user.email).isPresent());
}
Why is my test passing ?

As I can see here https://github.com/playframework/playframework/blob/master/framework/src/play-java-forms/src/main/java/play/data/validation/Constraints.java the isValid method of the EmailValidator class returns true if its agrument is an empty string:
public static class EmailValidator extends Validator<String> implements ConstraintValidator<Email, String> {
public boolean isValid(String object) {
if(object == null || object.length() == 0) {
return true;
}
return regex.matcher(object).matches();
}
}
Consider adding #Constraints.Requiredand #Formats.NonEmpty to this validation. Also, you can see that the MinLength and MaxLength validators behave in the same way.

Related

Parent, child and return types in Java

I am relatively new to Java. I have scenario where I want to return a child type object when a parent type of object is expected.
Sample Java code:
Parent def:
public class parentclass {
private String token;
private String userId;
public parentclass(String token, String userId)
{
this.token = token;
this.userId = userId;
}
}
Child 1 def:
public class childclass1 extends parentclass {
public String dept;
public childclass1(String token, String userId, String dept)
{
super(token, userId, dept);
}
//more code as needed
}
Child 2 def:
public class childclass2 extends parentclass {
public String college;
public childclass2(String token, String userId, String college)
{
super(token, userId, college);
}
//more code as needed
}
Caller:
public class1{
public parentclass verify_method(String Auth1, String Auth2) {
if (a)
return login1(Auth1);
else
return login2(Auth2);
}
}
Called:
public class2{
public childclass1 login1(String Auth){
//Do something
return childclass1;
}
public childclass2 login2(String Auth){
//Do something
return childclass2;
}
}
In above example, my caller is erroneous as return object type do not match. Please advise how do I modify the code so that I could achieve what I wanted..
The parent constructor only have two fields, you'll have to put the child-class field separately, like this:
public childclass1(String token, String userId, String dept)
{
super(token, userId);
this.dept = dept;
}

Mockito: Wanting but not invoked

I want to test this method:
if (user != null) {
userDAO.delete(user);
sessionService.logout(user.getEmail());
}
}
this is my Test:
public void deleteTest(){
doNothing().when(userDAO).delete(user);
doNothing().when(sessionService).logout("");
sessionInvalidationDecorator.delete(user);
verify(userDAO, times(1)).delete(user);
verify(sessionService, times(1)).logout("");
}
but I get:
Wanted but not invoked:
sessionService.logout("");
-> at de.unibremen.swp.controller.SessionInvalidationDecoratorTest.deleteTest(SessionInvalidationDecoratorTest.java:69)
Actually, there were zero interactions with this mock.
I don't know what I do wrong
Thanks in advance.
The problem was that you are indicating the value that logout must have, in this case when it is mocked, and referring to user.getEmail() is waiting for you to return a " " and instead you are returning a string from getEmail
I guess that your user.getMail does not return the empty string that you verify.
You have to make sure that user.getMail returns a string that is equal to the one you verify.
Here is a complete example that works.
public class SessionInvalidationDecoratorTest {
private UserDAO userDAOMock;
private SessionService sessionServiceMock;
private SessionInvalidationDecorator sessionInvalidationDecorator;
#Before
public void setup() {
userDAOMock = Mockito.mock(UserDAO.class);
sessionServiceMock = Mockito.mock(SessionService.class);
sessionInvalidationDecorator = new SessionInvalidationDecorator(userDAOMock, sessionServiceMock);
}
#Test
public void deleteTest() {
User user = new User();
user.setEmail("mail#some-domain.com");
sessionInvalidationDecorator.delete(user);
Mockito.verify(userDAOMock, Mockito.times(1)).delete(user);
Mockito.verify(sessionServiceMock, Mockito.times(1)).logout("mail#some-domain.com");
}
}
public class SessionInvalidationDecorator {
private UserDAO userDAO;
private SessionService sessionService;
public SessionInvalidationDecorator(UserDAO userDAO, SessionService sessionService) {
this.userDAO = userDAO;
this.sessionService = sessionService;
}
public void delete(User user) {
if (user != null) {
userDAO.delete(user);
sessionService.logout(user.getEmail());
}
}
}
public interface SessionService {
void logout(String email);
}
public interface UserDAO {
void delete(User user);
}
public class User {
private String email;
public void setEmail(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
}

How to get access to a HashMap of objects from the Objects in that HashMap. (Java)

I have a hash map of some POJO Objects of a Class named User: HashMap<ObjectId, User>
These objects (Users) are related to each other. (I need to search through other users to Update one's Parameters)
How can I have access to the HashMap within a user object?
import org.bson.types.ObjectId;
import org.bson.BsonDocument;
import java.util.ArrayList;
import java.util.List;
public class User {
private ObjectId _id;
private int grade;
private String region;
private ArrayList<ObjectId> _reg_by;
private ObjectId regBy;
public User(){
}
public ObjectId getId() {
return _id;
}
public void setId(final ObjectId id) {
this._id = id;
}
public int getGrade() {
return grade;
}
public void setGrade(final int grade) {
this.grade = grade;
}
public String getRegion() {
return region;
}
public void setRegion(final String region) {
this.region = region;
}
public ObjectId getRegBy() {
if(regBy == null) {
regBy = ((_reg_by.size() != 0) ? _reg_by.get(0) : null);
}
return regBy;
}
public void setRegBy(final ObjectId regBy) {
this.regBy = regBy;
}
public ArrayList<ObjectId> get_reg_by(){
return _reg_by;
}
public void set_reg_by(ArrayList<ObjectId> _reg_by){
this._reg_by = _reg_by;
}
private String updateRegion(){
if(getRegBy() == null)
return null;
//TODO search for the person who registered him and use the region!
// how to get access to others from here?!
}
}
This is the User class where in regionUpdate() function I want to have this access
I creat this HashMap in my Main function.
HashMap<ObjectId, User> users = mongoHandler.getUsers();
I solved my problem by defining my HashMap as Static.
public static HashMap<ObjectId, User> users
so I can easily have access to it from anywhere by using the following code:
HashMap<ObjectId, User> users = Main.users
or any method e.g. Main.users.getId();
Another solution could have been to create a property within your "User" class that contains a list of related users, and if you know that one user is related to another, added it to the each user as you build the list.
public class User {
...
private List<User> relatedUsers = new ArrayList<User>();
...
private void updateRelatedUsers() {
for(User relatedUser : relatedUsers) {
//do stuff to update the relatedUser object.
relatedUser.setSomething(someValue);
}
}
//Getter and setter
public List<User> getRelatedUsers() {
return relatedUsers;
}
public void setRelatedUsers(List<User> relatedUsers) {
this.relatedUsers = relatedUsers;
}
...
}
Add the users like so:
...
User myUser = creatUserHoweverYouDo();
User myRelatedUser = getMyRelatedUser(myUser);
myUser.getRelatedUsers().add(myRelatedUser);
...

Firebase: No properties to serialise - Android

I'm running into problems trying to read and write data to/from my Firebase realtime database. I have a register and login activity. When I register a user, I want to authenticate them and add the User's data to the database.
Here is my User class:
public class myUser {
public static boolean onlineStatus;
public static int userAge;
public static String userGender;
public static String userId;
public static String userName;
public myUser() {
}
//Default constructor will have/set the default info for the users such as:
//(auto generated) id name, age, and gender initialised at creation time
public myUser(boolean onlineStatus, int userAge, String userGender, String userId, String userName ) {
this.onlineStatus = onlineStatus;
this.userAge = userAge;
this.userGender = userGender;
this.userId = userId;
this.userName = userName;
}
//Getters
public static String getUserId() {
return userId;
}
public static String getUserName() {
return userName;
}
public static int getUserAge() {
return userAge;
}
public static String getUserGender() {
return userGender;
}
public static boolean getOnlineStatus() {
return onlineStatus;
}
//Setters
public static void setOnlineStatusTrue() {
onlineStatus = true;
}
public static void setOnlineStatusFalse() {
onlineStatus = false;
}
}
Now when I set a Database reference to my User object like so:
String id = databaseUsers.push().getKey();
myUser userRef = new myUser(onlineStatus, age, gender, id, name );
databaseUsers.setValue(userRef);
Now when I go register a user in my register activity my App crashes and I get the following error:
No properties to serialise:
(https://puu.sh/A08NT.png
I've also added some ProGuard rules but I still get the same error.
-keepattributes Signature
-keepclassmembers class com.example.teamc.friendfinder.** {
*;
}
All I would like to do is to register a user, add them to the database and set their online status to False. Then when the user signs in I'd like to set it to True so I'm able to get their online status activity and update the UI.
To solve your problem, please use the following steps.
Change all your fileds from your model class from public static to private.
private boolean onlineStatus;
private int userAge;
private String userGender;
private String userId;
private String userName;
Change all your setters and getters from your model class from public static to only public.

Form validation with Binder

How to finish validation with sending all form data in Vaadin 8? Unfortunetly I dont understand binder concept :( I wrote a field validation but what now? It works. My user see when I demand that he fill out a field but is there any easy way to validate my all form? How can I "tell" to my save button that my form is valid?
In my editor Im defining a validator
#SpringComponent
#PrototypeScope
public class VaadinStringEditor extends TextField implements HasValueComponent<String> {
private Binder<String> binder;
BinderValidationStatus<String> status;
#PostConstruct
public void init() {
setWidth("100%");
binder = new Binder<>();
}
#Override
public void initDefaults() {
setValue("");
status = binder.validate();
}
#Override
public void setConfiguration(EditorConfiguration editorConfiguration) {
Validator<String> validator = ((TextFieldConfiguration) editorConfiguration).getValidator();
if (validator != null) {
binder.forField(this).withValidator(validator).asRequired("Mandatory").bind(s -> getValue(),
(b, v) -> setValue(v));
}
public BinderValidationStatus<String> getStatus() {
return status;
}
public void setStatus(BinderValidationStatus<String> status) {
this.status = status;
}
public boolean validate() {
BinderValidationStatus<String> status = binder.validate();
return status.isOk();
}
}
}
I have also an TextEditorConfiguration added:
public class TextFieldConfiguration implements EditorConfiguration {
private Validator<String> validator;
private int validated;
public TextFieldConfiguration(Validator<String> validator) {
this.validator = validator;
}
public TextFieldConfiguration() {
this.validator = null;
}
public Validator<String> getValidator() {
return validator;
}
public int getValidated() {
return validated;
}
public void setValidated(int validated) {
this.validated = validated;
}
}
In my case there are plenty of editors like DateEditor and so on. UI Valtidation works well. Since one month I can not find a way how to connect it to submit button to prevent send a form.
In the form class I have defined all questions
for example:
question = new AseQuestion(AseQuestionId.DATE_OF_NOTIFICATION, EditorType.DATE_EDITOR);
question.setDescription(
"When it happend?");
question.setEditorConfiguration(new DateFieldConfiguration(dateRequiredValidator(), dateNotAllowedValidator()));
return question;
question = new AseQuestion(AseQuestionId.QUESTION2, EditorType.STRING_EDITOR);
question.setDescription("
"Write something");
private Validator<String> textRequiredValidator() {
return Validator.from(v -> v != null && StringUtils.trimAllWhitespace((String) v).length() != 0,
"It cannot be empty!!!");
And the class where I have a submit button
public class QuestionWindow extends Window {
#Autowired
private transient VaadinStringEditor editor;
private Button createSaveButton() {
Button saveButton = new Button(i18n.getWithDefault("newAseQuestions.save", "Übernehmen"));
saveButton.addClickListener(e -> {
if (editor.getBinder.validate()) {
Notification.show("This is the caption OK", "This is the description",
Notification.Type.HUMANIZED_MESSAGE);
} else {
Notification.show("This is the caption", "This is the description",
Notification.Type.HUMANIZED_MESSAGE);
System.out.println("kurwa");
}
saveAse();
});
return saveButton;
}
OK lets assume we haven this POJO:
public class Person {
private String firstname;
private String lastname;
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
}
And we want to edit it.
So we build the following form:
public class Form {
private TextField firstname;
private TextField lastname;
private Binder<Person> binder = new Binder<>();
void bindFields() {
binder.forField(firstname).withValidator(textRequiredValidator())
.asRequired("Mandatory").bind(Person::getFirstname, Person::setFirstname);
binder.forField(lastname).withValidator(textRequiredValidator())
.asRequired("Mandatory").bind(Person::getLastname, Person::setLastname);
}
public void setDatasource(Person person) {
binder.setBean(person);
}
private Validator<String> textRequiredValidator() {
return Validator.from(v -> v != null && StringUtils.trimAllWhitespace((String) v).length() != 0,
"It cannot be empty!!!");
}
public boolean validate() {
BinderValidationStatus<Person> status = binder.validate();
return status.isOk();
}
}
In order to use this form we need to call bindFields first (e.g. constructor, init).
Than a controller or so calls setDatasource with the person we want to edit.
After this the user can fill or edit the form and when the user finishes the status of the form can be retrieved via validate.
If you need the errors from the fields you get them from the BinderValidationStatus.
For more information look at https://vaadin.com/docs/v8/framework/datamodel/datamodel-forms.html

Categories