diff --git a/README.md b/README.md index 1439356b..b30cfe66 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ or you can add a maven dependency since it is now available in Maven central: com.mmnaseri.utils spring-data-mock - ${latest-version} + ${spring-data-mock.version} test @@ -52,7 +52,7 @@ using [Maven exclusions](https://maven.apache.org/guides/introduction/introducti com.mmnaseri.utils spring-data-mock - ${latest-version} + ${spring-data-mock.version} test diff --git a/spring-data-mock-sample-jpa/pom.xml b/spring-data-mock-sample-jpa/pom.xml index 1d32911c..13814e9e 100644 --- a/spring-data-mock-sample-jpa/pom.xml +++ b/spring-data-mock-sample-jpa/pom.xml @@ -35,7 +35,7 @@ 1.12.1.RELEASE 1.10.1.RELEASE 1.0.2 - 1.1.3 + 1.1.4 6.9.6 1.3 UTF-8 diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/model/Group.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/model/Group.java new file mode 100644 index 00000000..6e303bb7 --- /dev/null +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/model/Group.java @@ -0,0 +1,33 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.model; + +import javax.persistence.Entity; +import javax.persistence.Id; + +/** + * @author Milad Naseri (milad.naseri@cdk.com) + * @since 1.0 (6/29/16, 4:03 PM) + */ +@Entity +public class Group { + + @Id + private String id; + private String name; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/model/Membership.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/model/Membership.java new file mode 100644 index 00000000..c91bee86 --- /dev/null +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/model/Membership.java @@ -0,0 +1,45 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.model; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; + +/** + * @author Milad Naseri (milad.naseri@cdk.com) + * @since 1.0 (6/29/16, 4:04 PM) + */ +@Entity +public class Membership { + + @Id + private String id; + @ManyToOne + private User user; + @ManyToOne + private Group group; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public Group getGroup() { + return group; + } + + public void setGroup(Group group) { + this.group = group; + } + +} diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/model/User.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/model/User.java new file mode 100644 index 00000000..f76dc40f --- /dev/null +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/model/User.java @@ -0,0 +1,51 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.model; + +import javax.persistence.Entity; +import javax.persistence.Id; + +/** + * @author Milad Naseri (milad.naseri@cdk.com) + * @since 1.0 (6/29/16, 4:03 PM) + */ +@Entity +public class User { + + @Id + private String id; + private String username; + private String email; + private String passwordHash; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPasswordHash() { + return passwordHash; + } + + public void setPasswordHash(String passwordHash) { + this.passwordHash = passwordHash; + } + +} diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/GroupRepository.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/GroupRepository.java new file mode 100644 index 00000000..5098bf79 --- /dev/null +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/GroupRepository.java @@ -0,0 +1,11 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.repository; + +import com.mmnaseri.utils.samples.spring.data.jpa.model.Group; +import org.springframework.data.jpa.repository.JpaRepository; + +/** + * @author Milad Naseri (milad.naseri@cdk.com) + * @since 1.0 (6/29/16, 4:05 PM) + */ +public interface GroupRepository extends JpaRepository { +} diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/MembershipRepository.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/MembershipRepository.java new file mode 100644 index 00000000..1a90510f --- /dev/null +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/MembershipRepository.java @@ -0,0 +1,21 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.repository; + +import com.mmnaseri.utils.samples.spring.data.jpa.model.Group; +import com.mmnaseri.utils.samples.spring.data.jpa.model.Membership; +import com.mmnaseri.utils.samples.spring.data.jpa.model.User; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +/** + * @author Milad Naseri (milad.naseri@cdk.com) + * @since 1.0 (6/29/16, 4:06 PM) + */ +public interface MembershipRepository extends JpaRepository { + + List findByUser(User user); + + List findByGroup(Group group); + + Membership findByUserAndGroup(User user, Group group); +} diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/UserRepository.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/UserRepository.java new file mode 100644 index 00000000..4064c84b --- /dev/null +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/repository/UserRepository.java @@ -0,0 +1,18 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.repository; + +import com.mmnaseri.utils.samples.spring.data.jpa.model.User; +import org.springframework.data.jpa.repository.JpaRepository; + +/** + * @author Milad Naseri (milad.naseri@cdk.com) + * @since 1.0 (6/29/16, 4:05 PM) + */ +public interface UserRepository extends JpaRepository { + + User findByUsernameOrEmailAllIgnoreCase(String username, String email); + + User findByUsernameIgnoreCase(String username); + + User findByEmailIgnoreCase(String email); + +} diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/GroupService.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/GroupService.java new file mode 100644 index 00000000..3bbf9081 --- /dev/null +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/GroupService.java @@ -0,0 +1,25 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.service; + +import com.mmnaseri.utils.samples.spring.data.jpa.model.Group; +import com.mmnaseri.utils.samples.spring.data.jpa.model.User; + +import java.util.List; + +/** + * @author Milad Naseri (milad.naseri@cdk.com) + * @since 1.0 (6/29/16, 5:26 PM) + */ +public interface GroupService { + + Group createGroup(String name); + + void deleteGroup(Group group); + + void join(Group group, User user); + + void leave(Group group, User user); + + List members(Group group); + + List groups(User user); +} diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/UserService.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/UserService.java new file mode 100644 index 00000000..6f79f8d3 --- /dev/null +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/UserService.java @@ -0,0 +1,21 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.service; + +import com.mmnaseri.utils.samples.spring.data.jpa.model.User; + +/** + * @author Milad Naseri (milad.naseri@cdk.com) + * @since 1.0 (6/29/16, 4:06 PM) + */ +public interface UserService { + + User createUser(String username, String email, String password); + + void updatePassword(String handle, String oldPassword, String newPassword); + + void deleteUser(String handle); + + User lookup(String handle); + + User authenticate(String handle, String password); + +} diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultGroupService.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultGroupService.java new file mode 100644 index 00000000..cd179897 --- /dev/null +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultGroupService.java @@ -0,0 +1,81 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.service.impl; + +import com.mmnaseri.utils.samples.spring.data.jpa.model.Group; +import com.mmnaseri.utils.samples.spring.data.jpa.model.Membership; +import com.mmnaseri.utils.samples.spring.data.jpa.model.User; +import com.mmnaseri.utils.samples.spring.data.jpa.repository.GroupRepository; +import com.mmnaseri.utils.samples.spring.data.jpa.repository.MembershipRepository; +import com.mmnaseri.utils.samples.spring.data.jpa.service.GroupService; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Milad Naseri (milad.naseri@cdk.com) + * @since 1.0 (6/30/16, 9:16 AM) + */ +public class DefaultGroupService implements GroupService { + + private final GroupRepository groupRepository; + private final MembershipRepository membershipRepository; + + public DefaultGroupService(GroupRepository groupRepository, MembershipRepository membershipRepository) { + this.groupRepository = groupRepository; + this.membershipRepository = membershipRepository; + } + + @Override + public Group createGroup(String name) { + final Group group = new Group(); + group.setName(name); + return groupRepository.save(group); + } + + @Override + public void deleteGroup(Group group) { + final List memberships = membershipRepository.findByGroup(group); + membershipRepository.delete(memberships); + groupRepository.delete(group); + } + + @Override + public void join(Group group, User user) { + if (membershipRepository.findByUserAndGroup(user, group) != null) { + return; + } + final Membership membership = new Membership(); + membership.setGroup(group); + membership.setUser(user); + membershipRepository.save(membership); + } + + @Override + public void leave(Group group, User user) { + final Membership membership = membershipRepository.findByUserAndGroup(user, group); + if (membership == null) { + return; + } + membershipRepository.delete(membership); + } + + @Override + public List members(Group group) { + final List memberships = membershipRepository.findByGroup(group); + final List users = new ArrayList<>(); + for (Membership membership : memberships) { + users.add(membership.getUser()); + } + return users; + } + + @Override + public List groups(User user) { + final List memberships = membershipRepository.findByUser(user); + final List groups = new ArrayList<>(); + for (Membership membership : memberships) { + groups.add(membership.getGroup()); + } + return groups; + } + +} diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultUserService.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultUserService.java new file mode 100644 index 00000000..4266c98f --- /dev/null +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultUserService.java @@ -0,0 +1,78 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.service.impl; + +import com.mmnaseri.utils.samples.spring.data.jpa.model.Group; +import com.mmnaseri.utils.samples.spring.data.jpa.model.User; +import com.mmnaseri.utils.samples.spring.data.jpa.repository.UserRepository; +import com.mmnaseri.utils.samples.spring.data.jpa.service.GroupService; +import com.mmnaseri.utils.samples.spring.data.jpa.service.UserService; +import com.mmnaseri.utils.samples.spring.data.jpa.utils.EncryptionUtils; + +import java.util.List; + +/** + * @author Milad Naseri (milad.naseri@cdk.com) + * @since 1.0 (6/29/16, 4:09 PM) + */ +public class DefaultUserService implements UserService { + + private final UserRepository repository; + private final GroupService groupService; + + public DefaultUserService(UserRepository repository, GroupService groupService) { + this.repository = repository; + this.groupService = groupService; + } + + @Override + public User createUser(String username, String email, String password) { + if (repository.findByUsernameIgnoreCase(username) != null || repository.findByEmailIgnoreCase(email) != null) { + throw new IllegalArgumentException(); + } + final User user = new User(); + user.setUsername(username); + user.setEmail(email); + user.setPasswordHash(EncryptionUtils.encrypt(password)); + return repository.save(user); + } + + @Override + public void updatePassword(String handle, String oldPassword, String newPassword) { + final User user = authenticate(handle, oldPassword); + if (user == null) { + throw new IllegalStateException(); + } + user.setPasswordHash(EncryptionUtils.encrypt(newPassword)); + repository.save(user); + } + + @Override + public void deleteUser(String handle) { + final User user = lookup(handle); + if (user == null) { + throw new IllegalStateException(); + } + final List groups = groupService.groups(user); + for (Group group : groups) { + groupService.leave(group, user); + } + repository.delete(user); + } + + @Override + public User lookup(String handle) { + return repository.findByUsernameOrEmailAllIgnoreCase(handle, handle); + } + + @Override + public User authenticate(String handle, String password) { + final User user = lookup(handle); + if (user == null) { + return null; + } + if (user.getPasswordHash().equals(EncryptionUtils.encrypt(password))) { + return user; + } + return null; + } + +} diff --git a/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/utils/EncryptionUtils.java b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/utils/EncryptionUtils.java new file mode 100644 index 00000000..d150f9f6 --- /dev/null +++ b/spring-data-mock-sample-jpa/src/main/java/com/mmnaseri/utils/samples/spring/data/jpa/utils/EncryptionUtils.java @@ -0,0 +1,21 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.utils; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * @author Milad Naseri (milad.naseri@cdk.com) + * @since 1.0 (6/29/16, 4:10 PM) + */ +public class EncryptionUtils { + + public static String encrypt(String text) { + try { + final MessageDigest digest = MessageDigest.getInstance("SHA-1"); + return new String(digest.digest(text.getBytes())); + } catch (NoSuchAlgorithmException e) { + return text; + } + } + +} diff --git a/spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultGroupServiceTest.java b/spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultGroupServiceTest.java new file mode 100644 index 00000000..6900fc1a --- /dev/null +++ b/spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultGroupServiceTest.java @@ -0,0 +1,143 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.service.impl; + +import com.mmnaseri.utils.samples.spring.data.jpa.model.Group; +import com.mmnaseri.utils.samples.spring.data.jpa.model.Membership; +import com.mmnaseri.utils.samples.spring.data.jpa.model.User; +import com.mmnaseri.utils.samples.spring.data.jpa.repository.GroupRepository; +import com.mmnaseri.utils.samples.spring.data.jpa.repository.MembershipRepository; +import com.mmnaseri.utils.samples.spring.data.jpa.repository.UserRepository; +import com.mmnaseri.utils.samples.spring.data.jpa.service.GroupService; +import com.mmnaseri.utils.samples.spring.data.jpa.service.UserService; +import com.mmnaseri.utils.spring.data.dsl.factory.RepositoryFactoryBuilder; +import com.mmnaseri.utils.spring.data.dsl.factory.Start; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.util.List; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +/** + * @author Milad Naseri (milad.naseri@cdk.com) + * @since 1.0 (6/30/16, 9:15 AM) + */ +public class DefaultGroupServiceTest { + + private GroupService service; + private GroupRepository groupRepository; + private UserService userService; + private MembershipRepository membershipRepository; + + @BeforeMethod + public void setUp() throws Exception { + final Start builder = RepositoryFactoryBuilder.builder(); + groupRepository = builder.mock(GroupRepository.class); + membershipRepository = builder.mock(MembershipRepository.class); + final UserRepository userRepository = builder.mock(UserRepository.class); + service = new DefaultGroupService(groupRepository, membershipRepository); + userService = new DefaultUserService(userRepository, service); + } + + @Test + public void testCreatingAGroup() throws Exception { + assertThat(groupRepository.count(), is(0L)); + final String name = "My Group"; + final Group group = service.createGroup(name); + assertThat(group, is(notNullValue())); + assertThat(group.getName(), is(name)); + assertThat(groupRepository.count(), is(1L)); + final Group found = groupRepository.findOne(group.getId()); + assertThat(found, is(notNullValue())); + assertThat(found.getName(), is(name)); + } + + @Test + public void testDeletingAnEmptyGroup() throws Exception { + Group group = new Group(); + group.setName("My Group"); + group = groupRepository.save(group); + service.deleteGroup(group); + assertThat(groupRepository.count(), is(0L)); + } + + @Test + public void testEstablishingMembership() throws Exception { + Group group = new Group(); + group.setName("My Group"); + group = groupRepository.save(group); + final User user = userService.createUser("milad", "milad@domain.com", "123456"); + service.join(group, user); + assertThat(membershipRepository.count(), is(1L)); + final Membership membership = membershipRepository.findAll().get(0); + assertThat(membership, is(notNullValue())); + assertThat(membership.getGroup(), is(notNullValue())); + assertThat(membership.getGroup().getId(), is(group.getId())); + assertThat(membership.getUser(), is(notNullValue())); + assertThat(membership.getUser().getId(), is(user.getId())); + } + + @Test + public void testBreakingAMembership() throws Exception { + Group group = new Group(); + group.setName("My Group"); + group = groupRepository.save(group); + final User user = userService.createUser("milad", "milad@domain.com", "123456"); + final Membership membership = new Membership(); + membership.setUser(user); + membership.setGroup(group); + membershipRepository.save(membership); + service.leave(group, user); + assertThat(membershipRepository.count(), is(0L)); + } + + @Test + public void testListingGroupMembers() throws Exception { + Group group = new Group(); + group.setName("My Group"); + group = groupRepository.save(group); + final User user = userService.createUser("milad", "milad@domain.com", "123456"); + final Membership membership = new Membership(); + membership.setUser(user); + membership.setGroup(group); + membershipRepository.save(membership); + final List users = service.members(group); + assertThat(users, is(notNullValue())); + assertThat(users, hasSize(1)); + assertThat(users.get(0), is(notNullValue())); + assertThat(users.get(0).getId(), is(user.getId())); + } + + @Test + public void testListingUserGroups() throws Exception { + Group group = new Group(); + group.setName("My Group"); + group = groupRepository.save(group); + final User user = userService.createUser("milad", "milad@domain.com", "123456"); + final Membership membership = new Membership(); + membership.setUser(user); + membership.setGroup(group); + membershipRepository.save(membership); + final List groups = service.groups(user); + assertThat(groups, is(notNullValue())); + assertThat(groups, hasSize(1)); + assertThat(groups.get(0), is(notNullValue())); + assertThat(groups.get(0).getId(), is(group.getId())); + } + + @Test + public void testDeletingAGroupWithMembers() throws Exception { + Group group = new Group(); + group.setName("My Group"); + group = groupRepository.save(group); + final User user = userService.createUser("milad", "milad@domain.com", "123456"); + final Membership membership = new Membership(); + membership.setUser(user); + membership.setGroup(group); + membershipRepository.save(membership); + service.deleteGroup(group); + assertThat(groupRepository.count(), is(0L)); + assertThat(membershipRepository.count(), is(0L)); + } + +} diff --git a/spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultUserServiceTest.java b/spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultUserServiceTest.java new file mode 100644 index 00000000..b2d0e4b4 --- /dev/null +++ b/spring-data-mock-sample-jpa/src/test/java/com/mmnaseri/utils/samples/spring/data/jpa/service/impl/DefaultUserServiceTest.java @@ -0,0 +1,146 @@ +package com.mmnaseri.utils.samples.spring.data.jpa.service.impl; + +import com.mmnaseri.utils.samples.spring.data.jpa.model.Group; +import com.mmnaseri.utils.samples.spring.data.jpa.model.User; +import com.mmnaseri.utils.samples.spring.data.jpa.repository.GroupRepository; +import com.mmnaseri.utils.samples.spring.data.jpa.repository.MembershipRepository; +import com.mmnaseri.utils.samples.spring.data.jpa.repository.UserRepository; +import com.mmnaseri.utils.samples.spring.data.jpa.service.GroupService; +import com.mmnaseri.utils.spring.data.dsl.factory.RepositoryFactoryBuilder; +import com.mmnaseri.utils.spring.data.dsl.factory.Start; +import org.hamcrest.Matchers; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +/** + * @author Milad Naseri (milad.naseri@cdk.com) + * @since 1.0 (6/29/16, 4:11 PM) + */ +public class DefaultUserServiceTest { + + private DefaultUserService service; + private UserRepository repository; + private GroupService groupService; + private GroupRepository groupRepository; + + @BeforeMethod + public void setUp() throws Exception { + final Start builder = RepositoryFactoryBuilder.builder(); + groupRepository = builder.mock(GroupRepository.class); + final MembershipRepository membershipRepository = builder.mock(MembershipRepository.class); + groupService = new DefaultGroupService(groupRepository, membershipRepository); + repository = builder.mock(UserRepository.class); + service = new DefaultUserService(repository, groupService); + } + + @Test + public void testCreatingAUser() throws Exception { + assertThat(repository.count(), is(0L)); + final String username = "milad"; + final String email = "milad@mmnaseri.com"; + final String password = "123456"; + final User user = service.createUser(username, email, password); + assertThat(user, is(notNullValue())); + assertThat(user.getId(), is(notNullValue())); + assertThat(user.getUsername(), is(username)); + assertThat(user.getEmail(), is(email)); + assertThat(user.getPasswordHash(), is(not(password))); + assertThat(repository.count(), is(1L)); + final User found = repository.findOne(user.getId()); + assertThat(found, is(notNullValue())); + assertThat(found.getUsername(), is(username)); + assertThat(found.getEmail(), is(email)); + assertThat(found.getPasswordHash(), is(user.getPasswordHash())); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testCreatingADuplicateUser() throws Exception { + service.createUser("milad", "email1", "123456"); + service.createUser("milad", "email2", "123456"); + } + + @Test + public void testLookingUpAUserByEmail() throws Exception { + final String id = service.createUser("milad", "milad@domain.com", "123456").getId(); + final User found = service.lookup("MILAD@domain.com"); + assertThat(found, is(notNullValue())); + assertThat(found.getId(), is(id)); + } + + @Test + public void testLookingUpAUserByUsername() throws Exception { + final String id = service.createUser("milad", "milad@domain.com", "123456").getId(); + final User found = service.lookup("MILAD"); + assertThat(found, is(notNullValue())); + assertThat(found.getId(), is(id)); + } + + @Test + public void testLookingForNonExistentUser() throws Exception { + final User user = service.lookup("milad"); + assertThat(user, is(nullValue())); + } + + @Test + public void testAuthenticatingWithUsername() throws Exception { + final String id = service.createUser("milad", "milad@domain.com", "123456").getId(); + final User user = service.authenticate("Milad", "123456"); + assertThat(user, is(notNullValue())); + assertThat(user.getId(), is(id)); + } + @Test + public void testAuthenticatingWithEmail() throws Exception { + final String id = service.createUser("milad", "milad@domain.com", "123456").getId(); + final User user = service.authenticate("milad@DOMAIN.com", "123456"); + assertThat(user, is(notNullValue())); + assertThat(user.getId(), is(id)); + } + + @Test + public void testAuthenticatingWithWrongHandle() throws Exception { + service.createUser("milad", "milad@domain.com", "123456").getId(); + final User user = service.authenticate("milad@DOMAIN", "123456"); + assertThat(user, is(nullValue())); + } + + @Test + public void testAuthenticatingWithWrongPassword() throws Exception { + service.createUser("milad", "milad@domain.com", "123456").getId(); + final User user = service.authenticate("milad", "987654"); + assertThat(user, is(nullValue())); + } + + @Test + public void testDeletingAUser() throws Exception { + service.createUser("milad", "milad@mmaseri.com", "123456"); + assertThat(repository.count(), is(1L)); + service.deleteUser("milad"); + assertThat(repository.count(), is(0L)); + } + + @Test + public void testChangingUserPassword() throws Exception { + service.createUser("milad", "milad@mmnaseri.com", "123456"); + assertThat(service.authenticate("milad", "123456"), is(notNullValue())); + service.updatePassword("milad", "123456", "987654"); + assertThat(service.authenticate("milad", "123456"), is(nullValue())); + assertThat(service.authenticate("milad", "987654"), is(notNullValue())); + } + + @Test + public void testDeletingAUserThatIsPartOfMultipleGroups() throws Exception { + final User user = service.createUser("milad", "milad@mmnaseri.com", "123456"); + groupService.join(groupService.createGroup("Group 1"), user); + groupService.join(groupService.createGroup("Group 2"), user); + groupService.join(groupService.createGroup("Group 3"), user); + groupService.join(groupService.createGroup("Group 4"), user); + assertThat(groupService.groups(user), hasSize(4)); + service.deleteUser(user.getUsername()); + assertThat(groupService.groups(user), is(Matchers.empty())); + assertThat(groupRepository.count(), is(4L)); + } + +} \ No newline at end of file diff --git a/spring-data-mock/pom.xml b/spring-data-mock/pom.xml index cf9c348f..b34c88eb 100644 --- a/spring-data-mock/pom.xml +++ b/spring-data-mock/pom.xml @@ -27,7 +27,7 @@ com.mmnaseri.utils spring-data-mock - 1.1.3 + 1.1.4 Spring Data Mock A framework for mocking Spring Data repositories @@ -71,22 +71,22 @@ 1.2 2.9.4 - 6.9.11 + 6.9.12 1.3 1.6 2.10.4 - 3.0.0 + 3.0.1 2.8.2 1.6.7 2.7 4.2.0 - 1.12.1.RELEASE - 1.8.1.RELEASE - 1.10.1.RELEASE + 1.12.2.RELEASE + 1.8.2.RELEASE + 1.10.2.RELEASE 4.1.2 - 3.2.2 + 3.2.4 1.0.2 diff --git a/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/dsl/factory/RepositoryFactoryBuilder.java b/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/dsl/factory/RepositoryFactoryBuilder.java index 5fe97cdf..4a83b027 100644 --- a/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/dsl/factory/RepositoryFactoryBuilder.java +++ b/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/dsl/factory/RepositoryFactoryBuilder.java @@ -77,18 +77,22 @@ public static Start builder() { */ public static Start given(RepositoryFactoryConfiguration configuration) { final RepositoryFactoryBuilder builder = new RepositoryFactoryBuilder(); - builder.metadataResolver = configuration.getRepositoryMetadataResolver() != null ? configuration.getRepositoryMetadataResolver() : builder.metadataResolver; - builder.queryDescriptionExtractor = configuration.getDescriptionExtractor() != null ? configuration.getDescriptionExtractor() : builder.queryDescriptionExtractor; - builder.functionRegistry = configuration.getFunctionRegistry() != null ? configuration.getFunctionRegistry() : builder.functionRegistry; - builder.dataStoreRegistry = configuration.getDataStoreRegistry() != null ? configuration.getDataStoreRegistry() : builder.dataStoreRegistry; - builder.resultAdapterContext = configuration.getResultAdapterContext() != null ? configuration.getResultAdapterContext() : builder.resultAdapterContext; - builder.typeMappingContext = configuration.getTypeMappingContext() != null ? configuration.getTypeMappingContext() : builder.typeMappingContext; - builder.eventListenerContext = configuration.getEventListenerContext() != null ? configuration.getEventListenerContext() : builder.eventListenerContext; - builder.operationInvocationHandler = configuration.getOperationInvocationHandler() != null ? configuration.getOperationInvocationHandler() : builder.operationInvocationHandler; - builder.defaultKeyGenerator = configuration.getDefaultKeyGenerator() != null ? configuration.getDefaultKeyGenerator() : builder.defaultKeyGenerator; + builder.metadataResolver = getOrDefault(configuration.getRepositoryMetadataResolver(), builder.metadataResolver); + builder.queryDescriptionExtractor = getOrDefault(configuration.getDescriptionExtractor(), builder.queryDescriptionExtractor); + builder.functionRegistry = getOrDefault(configuration.getFunctionRegistry(), builder.functionRegistry); + builder.dataStoreRegistry = getOrDefault(configuration.getDataStoreRegistry(), builder.dataStoreRegistry); + builder.resultAdapterContext = getOrDefault(configuration.getResultAdapterContext(), builder.resultAdapterContext); + builder.typeMappingContext = getOrDefault(configuration.getTypeMappingContext(), builder.typeMappingContext); + builder.eventListenerContext = getOrDefault(configuration.getEventListenerContext(), builder.eventListenerContext); + builder.operationInvocationHandler = getOrDefault(configuration.getOperationInvocationHandler(), builder.operationInvocationHandler); + builder.defaultKeyGenerator = getOrDefault(configuration.getDefaultKeyGenerator(), builder.defaultKeyGenerator); return builder; } + private static E getOrDefault(E value, E defaultValue) { + return value != null ? value : defaultValue; + } + /** * @return the default factory */ diff --git a/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/proxy/impl/DefaultRepositoryFactory.java b/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/proxy/impl/DefaultRepositoryFactory.java index 9f9edbf4..470c809f 100644 --- a/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/proxy/impl/DefaultRepositoryFactory.java +++ b/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/proxy/impl/DefaultRepositoryFactory.java @@ -58,16 +58,19 @@ public DefaultRepositoryFactory(RepositoryFactoryConfiguration configuration) { @Override public E getInstance(KeyGenerator keyGenerator, Class repositoryInterface, Class... implementations) { + final KeyGenerator actualKeyGenerator; if (keyGenerator == null) { if (configuration.getDefaultKeyGenerator() != null) { //if no key generator is passed and there is a default key generator specified, we fall back to that - keyGenerator = configuration.getDefaultKeyGenerator(); + actualKeyGenerator = configuration.getDefaultKeyGenerator(); } else { //otherwise, let's assume that not key generation is required - keyGenerator = new NoOpKeyGenerator<>(); + actualKeyGenerator = new NoOpKeyGenerator<>(); } + } else { + actualKeyGenerator = keyGenerator; } - log.info("We are going to create a proxy instance of type " + repositoryInterface + " using key generator " + keyGenerator + " and binding the implementations to " + Arrays.toString(implementations)); + log.info("We are going to create a proxy instance of type " + repositoryInterface + " using key generator " + actualKeyGenerator + " and binding the implementations to " + Arrays.toString(implementations)); //figure out the repository metadata log.info("Resolving repository metadata for " + repositoryInterface); final RepositoryMetadata metadata = getRepositoryMetadata(repositoryInterface); @@ -76,7 +79,7 @@ public E getInstance(KeyGenerator keyGenerator, Clas final DataStore dataStore = getDataStore(metadata); //figure out type mappings log.info("Trying to find all the proper type mappings for entity repository " + repositoryInterface); - final List> typeMappings = getTypeMappings(metadata, dataStore, keyGenerator, implementations); + final List> typeMappings = getTypeMappings(metadata, dataStore, actualKeyGenerator, implementations); //set up the data operation resolver final DataOperationResolver operationResolver = new DefaultDataOperationResolver(typeMappings, descriptionExtractor, metadata, functionRegistry, configuration); //get all of this repository's methods @@ -90,7 +93,7 @@ public E getInstance(KeyGenerator keyGenerator, Clas boundImplementations.add(mapping.getType()); } //set up the repository configuration - final RepositoryConfiguration repositoryConfiguration = new ImmutableRepositoryConfiguration(metadata, keyGenerator, boundImplementations); + final RepositoryConfiguration repositoryConfiguration = new ImmutableRepositoryConfiguration(metadata, actualKeyGenerator, boundImplementations); //create the interceptor //noinspection unchecked final InvocationHandler interceptor = new DataOperationInvocationHandler(repositoryConfiguration, invocationMappings, dataStore, adapterContext, operationInvocationHandler); diff --git a/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/query/impl/DefaultQueryDescriptor.java b/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/query/impl/DefaultQueryDescriptor.java index 2d79a971..7873a8ce 100644 --- a/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/query/impl/DefaultQueryDescriptor.java +++ b/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/query/impl/DefaultQueryDescriptor.java @@ -91,11 +91,19 @@ public boolean matches(Object entity, Invocation invocation) { for (List branch : branches) { boolean matches = true; for (Parameter parameter : branch) { - final Object value = wrapper.getPropertyValue(parameter.getPath()); + final boolean ignoreCase; + ignoreCase = parameter.getModifiers().contains(Modifier.IGNORE_CASE); + Object value = wrapper.getPropertyValue(parameter.getPath()); + if (ignoreCase && value != null && value instanceof String) { + value = ((String) value).toLowerCase(); + } final Operator operator = parameter.getOperator(); final Object[] properties = new Object[operator.getOperands()]; for (int i = 0; i < operator.getOperands(); i++) { properties[i] = invocation.getArguments()[parameter.getIndices()[i]]; + if (ignoreCase && properties[i] != null && properties[i] instanceof String) { + properties[i] = ((String) properties[i]).toLowerCase(); + } } if (!operator.getMatcher().matches(parameter, value, properties)) { matches = false;