<repo_name>xSaintBurrito/GymApp<file_sep>/userDBAndAuthentication/src/main/java/com/gymapp/gymapp/UserBO.java
package com.gymapp.gymapp;

import com.gymapp.gymapp.entity.FitnessClass;
import com.gymapp.gymapp.entity.User;
import com.gymapp.gymapp.input.UserAddInput;

import java.util.Set;

public interface UserBO {
    boolean setRole(long id, Role role);
    boolean changePassword(long userId, String password);
    boolean isMatchingPassword(long userId, String password);
    User addUser(UserAddInput userAddInput);
    boolean deleteUser(long userId);
    boolean changeUsername(long userId, String newUsername);
    boolean addFitnessClass(long userId, FitnessClass fitnessClass);
    Role getUserRole(long userId);
}
<file_sep>/userDBAndAuthentication/src/main/java/com/gymapp/gymapp/input/UserAddInput.java
package com.gymapp.gymapp.input;

import com.gymapp.gymapp.Role;
import com.gymapp.gymapp.entity.FitnessClass;
import lombok.Builder;
import lombok.Getter;

import java.util.Collection;
import java.util.List;

@Getter
@Builder
public class UserAddInput {

    private final String username;
    private final String password;
    private final Role role;
    private final List<FitnessClass> fitnessClasses;
}

<file_sep>/userDBAndAuthentication/src/test/java/com/gymapp/gymapp/bo/UserBOImplTest.java
package com.gymapp.gymapp.bo;

import com.gymapp.gymapp.Role;
import com.gymapp.gymapp.bo.UserBOImpl;
import com.gymapp.gymapp.entity.User;
import com.gymapp.gymapp.factory.UserFactory;
import com.gymapp.gymapp.input.UserAddInput;
import com.gymapp.gymapp.repository.UserRepository;
import com.gymapp.gymapp.validator.PasswordValidator;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.time.LocalDateTime;
import java.util.*;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class UserBOImplTest {

    private UserBOImpl userBOImpl;

    @Mock
    private UserRepository userRepository;

    @Mock
    private UserFactory userFactory;

    @Mock
    private PasswordEncoder passwordEncoder;

    @Mock
    private PasswordValidator passwordValidator;

    private long id;
    private String username;
    private String password;
    private Role role;

    @Before
    public void setUp() throws Exception {
        this.userBOImpl = new UserBOImpl(userRepository,
                userFactory,
                passwordEncoder,
                passwordValidator);

        this.id = 1L;
        this.username = "user";
        this.password = "<PASSWORD>";
        this.role = Role.MANAGER;
    }

    @After
    public void tearDown() throws Exception {
        this.userBOImpl = null;
    }

    @Test
    public void shouldAddUserWithoutRoles() {
        //given
        User user = mock(User.class);
        UserAddInput userAddInput = UserAddInput.builder()
                .username(username)
                .password(<PASSWORD>)
                .role(Role.MANAGER)
                .build();
        when(userFactory.create(userAddInput))
                .thenReturn(user);
        when(userRepository.save(user))
                .thenReturn(user);

        //when
        User result = userBOImpl.addUser(userAddInput);

        //then
        verify(userFactory)
                .create(userAddInput);
        verify(userRepository)
                .save(user);
        assertThat(result)
                .isNotNull();
    }

    @Test
    public void shouldAddUserWithRoles() {
        //given
        User user = mock(User.class);
        UserAddInput userAddInput = UserAddInput.builder()
                .username(username)
                .password(<PASSWORD>)
                .role(role)
                .build();
        when(userFactory.create(userAddInput))
                .thenReturn(user);
        when(userRepository.save(user))
                .thenReturn(user);

        //when
        User result = userBOImpl.addUser(userAddInput);

        //then
        verify(userFactory)
                .create(userAddInput);
        verify(userRepository)
                .save(user);
        assertThat(result)
                .isNotNull();
    }

    @Test
    public void shouldGrantRoleToUser() {
        //given
        Role role = Role.MANAGER;
        User user = mock(User.class);

        when(userRepository.getOne(id))
                .thenReturn(user);

        //when
        userBOImpl.setRole(id, role);

        //then
        verify(userRepository)
                .getOne(id);
        verify(user)
                .setRole(role);
    }


    @Test
    public void shouldDelete() {
        //given

        //when
        userBOImpl.deleteUser(1L);

        //then
        verify(userRepository)
                .deleteById(1L);
    }

    @Test
    public void shouldChangePassword() {
        //given
        String userName = "user";
        String newPassword = "<PASSWORD>";
        String newHash = "<PASSWORD>";
        User user = mock(User.class);

        when(userRepository.getOne(id))
                .thenReturn(user);
        when(passwordEncoder.encode(newPassword))
                .thenReturn(newHash);

        //when
        userBOImpl.changePassword(id, newPassword);

        //then
        verify(user)
                .updatePassword(newHash);
    }

}
<file_sep>/userDBAndAuthentication/src/main/java/com/gymapp/gymapp/entity/FitnessClass.java
package com.gymapp.gymapp.entity;

import com.sun.istack.internal.NotNull;
import lombok.Getter;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
public class FitnessClass {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    private long maxPlaces;

    @NotNull
    private LocalDateTime date;

    private long trainerId;

    //@Transient
    @ManyToMany(mappedBy = "fitnessClasses")
    private List<User> signedUsers;

    protected FitnessClass(){

    }

    public FitnessClass(final long maxPlaces, final LocalDateTime date, final long trainerId) {
        this.maxPlaces = maxPlaces;
        this.date = date;
        this.trainerId = trainerId;
        this.signedUsers = new ArrayList<>();
    }

    public LocalDateTime checkDate(){ return date; }

    public boolean checkForPlaces(){
        return signedUsers.size() < maxPlaces;
    }

    public void signUp(final User user){
        signedUsers.add(user);
    }

    public void signOff(final User user){
        signedUsers.remove(user);
    }

    public List<User> getUsers(){ return signedUsers; }

}
<file_sep>/userDBAndAuthentication/src/test/java/com/gymapp/gymapp/bo/FitnessClassBOImplTest.java
package com.gymapp.gymapp.bo;

import com.gymapp.gymapp.entity.FitnessClass;
import com.gymapp.gymapp.entity.User;
import com.gymapp.gymapp.repository.FitnessClassRepository;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class FitnessClassBOImplTest {

    private FitnessClassBOImpl fitnessClassBOImpl;

    @Mock
    private FitnessClassRepository fitnessClassRepository;

    private Long id;
    private long maxPlaces;
    private LocalDateTime date;
    private long trainerId;
    private List<User> signedUsers;
    private String username;
    private String password;

    @Before
    public void setUp() throws Exception {
        this.fitnessClassBOImpl = new FitnessClassBOImpl(fitnessClassRepository);

        this.id = 1L;
        this.username = "user";
        this.password = "<PASSWORD>";
        this.maxPlaces = 100;
        this.date = LocalDateTime.of(2010, 10, 10, 10, 10);
        this.trainerId = 1L;

    }

    @After
    public void tearDown() throws Exception {
        this.fitnessClassBOImpl = null;
    }

    @Test
    public void shouldAddFitnessClass() {
        //given
        FitnessClass fitnessClass = mock(FitnessClass.class);
        when(fitnessClassRepository.save(fitnessClass))
                .thenReturn(fitnessClass);

        //when
        boolean result = fitnessClassBOImpl.add(fitnessClass);

        //then
        assertThat(result)
                .isTrue();

    }

    @Test
    public void shouldRemoveFitnessClass() {
        //given
        FitnessClass fitnessClass = new FitnessClass(maxPlaces, date, trainerId);
        fitnessClassBOImpl.add(fitnessClass);

        //when
        boolean result = fitnessClassBOImpl.remove(fitnessClass);

        //then
        assertThat(result)
                .isTrue();
    }

}
<file_sep>/userDBAndAuthentication/src/main/resources/application.properties
spring.jpa.hibernate.ddl=org.hibernate.dialect.MySQLInnoDBDialect
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/gymapp?autoReconnect=true&useSSL=false
spring.datasource.username=gymapp
spring.datasource.password=<PASSWORD>
<file_sep>/userDBAndAuthentication/src/main/java/com/gymapp/gymapp/Constants.java
package com.gymapp.gymapp;

public final class Constants {
    public static final int MIN_PASSWORD_LENGTH = 5;

    private Constants() { }
}
<file_sep>/userDBAndAuthentication/src/main/java/com/gymapp/gymapp/bo/FitnessClassBOImpl.java
package com.gymapp.gymapp.bo;

import com.gymapp.gymapp.FitnessClassBO;
import com.gymapp.gymapp.entity.FitnessClass;
import com.gymapp.gymapp.entity.User;
import com.gymapp.gymapp.repository.FitnessClassRepository;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class FitnessClassBOImpl implements FitnessClassBO {

    private final FitnessClassRepository fitnessClassRepository;

    FitnessClassBOImpl(final FitnessClassRepository fitnessClassRepository) {
        this.fitnessClassRepository = fitnessClassRepository;
    }

    @Override
    public boolean isThereFitnessClassAtDate(LocalDateTime date) {
        List<FitnessClass> fitnessClasses = fitnessClassRepository.findAll().stream()
                .filter(fitnessClass -> date.isEqual(fitnessClass.checkDate()))
                .collect(Collectors.toList());

        return fitnessClasses.size() > 0;
    }

    @Override
    public List<User> whichUsersHaveClassesAtDate(LocalDateTime date) {
        List<FitnessClass> fitnessClasses = fitnessClassRepository.findAll().stream()
                .filter(fitnessClass -> date.isEqual(fitnessClass.checkDate()))
                .collect(Collectors.toList());

        List<User> activeUsers = new ArrayList<>();
        fitnessClasses.forEach(fitnessClass -> activeUsers.addAll(fitnessClass.getUsers()));
        return activeUsers;
    }

    @Override
    public boolean add(FitnessClass fitnessClass) {
        fitnessClassRepository.save(fitnessClass);
        return true;
    }

    @Override
    public boolean remove(FitnessClass fitnessClass) {
        fitnessClassRepository.delete(fitnessClass);
        return true;
    }
}
<file_sep>/worker/src/main/java/worker/Date.java
package worker;

/**
 * Defines the concept of Date.
 * @author <NAME> & <NAME>
 *
 */

public class Date {

	/**
	 * Holds the date in the dd/mm/aaaa format as a String.
	 */
	private String date;
	
	/**
	 * The Strings day, month and year hold the 3 elements of a date separately.
	 */
	private String day, month, year;
	
	/**
	 * Contructor for a Date.
	 * @param day
	 * @param month
	 * @param year
	 */
	public Date(String day, String month, String year) {
		this.date = day + "/" + month + "/" + year;
		this.day = day;
		this.month = month;
		this.year = year;
	}
	
	/**
	 * Returns the day of the Date.
	 * @return day
	 */
	public String getDay() {
		return day;
	}
	
	/**
	 * Returns the month of the Date.
	 * @return month
	 */
	public String getMonth() {
		return month;
	}
	
	/**
	 * Returns the year of the Date.
	 * @return year
	 */
	public String getYear() {
		return year;
	}
	
	/**
	 * Returns the full date in the predefined format.
	 * @return date
	 */
	public String toString() {
		return date;
	}
	
}
<file_sep>/worker/src/main/java/worker/ReportManager.java
package worker;

import java.util.ArrayList;

/**
 * Class that manages all the Reports.
 * @author <NAME> & <NAME>
 *
 */

public class ReportManager {
	
	private static ArrayList<Report> reports = new ArrayList<>();
	
	private static ReportManager rm = null;
	
	/**
	 * Private ReportManager() constructor so that we can apply the Singleton pattern.
	 * This is because we only need one instance of the ReportManager.
	 */
	private ReportManager() {}
	
	/**
	 * Implements the Singleton pattern with lazy initialization.
	 * @return The instance of the ReportManager. If it has not been created yet, this method calls the constructor and returns the new instance.
	 */
	public ReportManager getReportManagerInstance() {
		if (rm.equals(null)) {
			return new ReportManager();
		}
		else return rm;
	}
	
	/**
	 * Returns all the reports the worker has access to.
	 * @return All reports this worker can access.
	 */
	public ArrayList<Report> getAllGymsReports() {
		return reports;
	}
	
	/**
	 * Returns reports of work-outs filtered with some specifications.
	 * Filters by gym, date, client and activity.
	 * 
	 * Usage: search only reports from gymX -> getFilteredReports(gymX,null, null, null)
	 *        search only reports from a specific date and also a specific client -> getFilteredReports(null, date, client, null)
	 *        
	 * @return All the reports that correspond to the filters passed as parameters.
	 */
	public ArrayList<Report> getFilteredReports (Gym gym, Date date, Client client, Activity activity) {
		ArrayList<Report> filtered = reports;
		
		for (Report r : reports) {
			if ((!gym.equals(null) && !gym.equals(r.getGym())) || (!date.equals(null) && !date.equals(r.getDate())) 
					|| (!client.equals(null) && !client.equals(r.getClient())) || (!activity.equals(null) && !activity.equals(r.getActivity())))
				filtered.remove(r);
		}
		
		return filtered;
	}
	
	/**
	 * Changes the importance of the Reports.
	 * This is completed by removing or adding to the importantReports list of the Worker.
	 * @param report
	 */
	public void changeImportanceStatus(Worker w, Report r) {
		w.changeImportantStatus(r);
	}
	
	/**
	 * Makes the worker follow or unfollow a specific Report.
	 * This is completed by removing or adding to the reportsFollowed list of the Worker
	 */
	public void changeFollowStatus(Worker w, Report r) {
		w.changeFollowStatus(r);
	}
}




