From 30d3eefcd4395d51726af7ecaf4df1a712248e18 Mon Sep 17 00:00:00 2001 From: John Blum Date: Mon, 21 May 2018 22:50:39 -0700 Subject: [PATCH] Add the o.s.b.d.g.core.env.support.User class and ADT to model users with access to Pivotal CloudFoundry services. --- .../data/geode/core/env/support/User.java | 182 ++++++++++++++++ .../geode/core/env/support/UserUnitTests.java | 206 ++++++++++++++++++ 2 files changed, 388 insertions(+) create mode 100644 geode-spring-boot-starter/src/main/java/org/springframework/boot/data/geode/core/env/support/User.java create mode 100644 geode-spring-boot-starter/src/test/java/org/springframework/boot/data/geode/core/env/support/UserUnitTests.java diff --git a/geode-spring-boot-starter/src/main/java/org/springframework/boot/data/geode/core/env/support/User.java b/geode-spring-boot-starter/src/main/java/org/springframework/boot/data/geode/core/env/support/User.java new file mode 100644 index 00000000..74831b0d --- /dev/null +++ b/geode-spring-boot-starter/src/main/java/org/springframework/boot/data/geode/core/env/support/User.java @@ -0,0 +1,182 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package org.springframework.boot.data.geode.core.env.support; + +import java.util.Arrays; +import java.util.Optional; + +import org.springframework.util.Assert; +import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; + +/** + * The User class... + * + * @author John Blum + * @since 1.0.0 + */ +@SuppressWarnings("unused") +public class User implements Comparable { + + private Role role; + + private final String name; + + private String password; + + /** + * Factory method used to construct a new {@link User} initialized with the given {@link String name}. + * + * @param name {@link String} containing the name of the {@link User}. + * @return a new {@link User} initialized witht he given {@link String name}. + * @throws IllegalArgumentException if {@link String name} is {@literal null} or empty. + * @see #User(String) + */ + public static User with(String name) { + return new User(name); + } + + /** + * Constructs a new {@link User} initialized with the given {@link String name}. + * + * @param name {@link String} containing the name of the {@link User}. + * @throws IllegalArgumentException if {@link String name} is {@literal null} or empty. + */ + private User(String name) { + + Assert.hasText(name, String.format("User name [%s] is required", name)); + + this.name = name; + } + + /** + * Returns the {@link String name} of this {@link User}. + * + * @return a {@link String} containing the {@link User User's} name. + */ + public String getName() { + return this.name; + } + + /** + * Returns an {@link Optional} {@link String} containing {@link User User's} password. + * + * @return an {@link Optional} {@link String} containing {@link User User's} password. + * @see java.util.Optional + */ + public Optional getPassword() { + return Optional.ofNullable(this.password).filter(StringUtils::hasText); + } + + /** + * Returns an {@link Optional} {@link Role} for this {@link User}. + * + * @return an {@link Optional} {@link Role} for this {@link User}. + * @see org.springframework.boot.data.geode.core.env.support.User.Role + * @see java.util.Optional + */ + public Optional getRole() { + return Optional.ofNullable(this.role); + } + + /** + * Builder method used to set this {@link User User's} {@link String password}. + * + * @param password {@link String} containing this {@link User User's} password. + * @return this {@link User}. + */ + public User withPassword(String password) { + this.password = password; + return this; + } + + /** + * Builder method used to set this {@link User User's} {@link Role}. + * + * @param role assigned {@link Role} of this {@link User}. + * @return this {@link User}. + * @see org.springframework.boot.data.geode.core.env.support.User + */ + public User withRole(Role role) { + this.role = role; + return this; + } + + @Override + @SuppressWarnings("all") + public int compareTo(User other) { + return this.getName().compareTo(other.getName()); + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof User)) { + return false; + } + + User that = (User) obj; + + return this.getName().equals(that.getName()); + } + + @Override + public int hashCode() { + + int hashValue = 17; + + hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getName()); + + return hashValue; + } + + @Override + public String toString() { + return getName(); + } + + public enum Role { + + CLUSTER_OPERATOR, + DEVELOPER; + + public static Role of(String name) { + + return Arrays.stream(values()) + .filter(role -> role.name().equalsIgnoreCase(String.valueOf(name).trim())) + .findFirst() + .orElse(null); + } + + public boolean isClusterOperator() { + return CLUSTER_OPERATOR.equals(this); + } + + public boolean isDeveloper() { + return DEVELOPER.equals(this); + } + + @Override + public String toString() { + return name().toLowerCase(); + } + } +} diff --git a/geode-spring-boot-starter/src/test/java/org/springframework/boot/data/geode/core/env/support/UserUnitTests.java b/geode-spring-boot-starter/src/test/java/org/springframework/boot/data/geode/core/env/support/UserUnitTests.java new file mode 100644 index 00000000..88ec4769 --- /dev/null +++ b/geode-spring-boot-starter/src/test/java/org/springframework/boot/data/geode/core/env/support/UserUnitTests.java @@ -0,0 +1,206 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package org.springframework.boot.data.geode.core.env.support; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; + +import org.junit.Test; + +/** + * Unit tests for {@link User}. + * + * @author John Blum + * @see org.junit.Test + * @see org.springframework.boot.data.geode.core.env.support.User + * @since 1.0.0 + */ +public class UserUnitTests { + + @Test + public void withNameReturnsNewUser() { + + User user = User.with("root"); + + assertThat(user).isNotNull(); + assertThat(user.getName()).isEqualTo("root"); + assertThat(user.getPassword().isPresent()).isFalse(); + assertThat(user.getRole().isPresent()).isFalse(); + } + + @Test + public void withNamePasswordAndRoleReturnsNewUser() { + + User jdoe = User.with("jdoe") + .withPassword("p@55w0rd!") + .withRole(User.Role.CLUSTER_OPERATOR); + + assertThat(jdoe).isNotNull(); + assertThat(jdoe.getName()).isEqualTo("jdoe"); + assertThat(jdoe.getPassword().orElse(null)).isEqualTo("p@55w0rd!"); + assertThat(jdoe.getRole().orElse(null)).isEqualTo(User.Role.CLUSTER_OPERATOR); + } + + private void testWithInvalidNameThrowsIllegalArgumentException(String name) { + + try { + User.with(name); + } + catch (IllegalArgumentException expected) { + + assertThat(expected).hasMessage("User name [%s] is required", name); + assertThat(expected).hasNoCause(); + + throw expected; + } + } + + @Test(expected = IllegalArgumentException.class) + public void withBlankUserNameThrowsIllegalArgumentException() { + testWithInvalidNameThrowsIllegalArgumentException(" "); + } + + @Test(expected = IllegalArgumentException.class) + public void withEmptyUserNameThrowsIllegalArgumentException() { + testWithInvalidNameThrowsIllegalArgumentException(""); + } + + @Test(expected = IllegalArgumentException.class) + public void withNullUserNameThrowsIllegalArgumentException() { + testWithInvalidNameThrowsIllegalArgumentException(null); + } + + @Test + public void compareToReturnsEqualValue() { + assertThat(User.with("root").compareTo(User.with("root"))).isEqualTo(0); + } + + @Test + public void compareToReturnsNegativeValue() { + assertThat(User.with("jdoe").compareTo(User.with("root"))).isLessThan(0); + } + + @Test + public void compareToReturnsPositiveValue() { + assertThat(User.with("root").compareTo(User.with("jdoe"))).isGreaterThan(0); + } + + @Test + @SuppressWarnings("all") + public void equalsObjectsReturnsFalse() { + assertThat(User.with("admin").equals("admin")).isFalse(); + } + + @Test + public void equalsWithDifferentObjectsReturnsFalse() { + + User admin = User.with("admin").withRole(User.Role.CLUSTER_OPERATOR); + User root = User.with("root").withRole(User.Role.CLUSTER_OPERATOR); + + assertThat(root.equals(admin)).isFalse(); + } + + @Test + public void equalsWithEqualObjectsReturnsTrue() { + + User root = User.with("root").withRole(User.Role.CLUSTER_OPERATOR); + User rootToo = User.with("root").withPassword("test").withRole(User.Role.DEVELOPER); + + assertThat(root.equals(rootToo)).isTrue(); + } + + @Test + @SuppressWarnings("all") + public void equalsWithIdenticalObjectsReturnsTrue() { + + User root = User.with("root"); + + assertThat(root.equals(root)).isTrue(); + } + + @Test + public void hashCodeIsCorrect() { + + User user = User.with("root"); + + int hashCode = user.hashCode(); + + assertThat(hashCode).isNotZero(); + assertThat(hashCode).isEqualTo(user.hashCode()); + + user.withPassword("test").withRole(User.Role.DEVELOPER); + + assertThat(user.hashCode()).isEqualTo(hashCode); + assertThat(user.hashCode()).isNotEqualTo(User.with("anotherUser").hashCode()); + } + + @Test + public void toStringReturnsUserName() { + assertThat(User.with("root").toString()).isEqualTo("root"); + } + + @Test + public void roleOfEmptyNameReturnsNull() { + assertThat(User.Role.of("")).isNull(); + assertThat(User.Role.of(" ")).isNull(); + } + + @Test + public void roleOfInvalidNameReturnsNull() { + assertThat(User.Role.of("invalid")).isNull(); + } + + @Test + public void roleOfNulReturnsNull() { + assertThat(User.Role.of(null)).isNull(); + } + + @Test + public void roleOfRoleNamesEqualsRole() { + Arrays.stream(User.Role.values()).forEach(role -> { + assertThat(User.Role.of(role.name())).isEqualTo(role); + assertThat(User.Role.of(role.toString())).isEqualTo(role); + }); + } + + @Test + public void isClusterOperator() { + assertThat(User.Role.CLUSTER_OPERATOR.isClusterOperator()).isTrue(); + } + + @Test + public void isNotClusterOperator() { + assertThat(User.Role.DEVELOPER.isClusterOperator()).isFalse(); + } + + @Test + public void isDeveloper() { + assertThat(User.Role.DEVELOPER.isDeveloper()).isTrue(); + } + + @Test + public void isNotDeveloper() { + assertThat(User.Role.CLUSTER_OPERATOR.isDeveloper()).isFalse(); + } + + @Test + public void toStringReturnsLowercaseName() { + Arrays.stream(User.Role.values()) + .forEach(role -> assertThat(role.toString()).isEqualTo(role.name().toLowerCase())); + } +}