Skip to content
12 changes: 12 additions & 0 deletions src/main/java/edu/tamu/app/config/AppEmailConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package edu.tamu.app.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

import edu.tamu.weaver.email.config.WeaverEmailConfig;

@Configuration
@Profile("!test")
public class AppEmailConfig extends WeaverEmailConfig {

}
13 changes: 13 additions & 0 deletions src/main/java/edu/tamu/app/controller/IdeaController.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package edu.tamu.app.controller;

import static edu.tamu.weaver.response.ApiStatus.SUCCESS;
import static edu.tamu.weaver.response.ApiStatus.INVALID;
import static edu.tamu.weaver.validation.model.BusinessValidationType.CREATE;

import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -52,6 +53,18 @@ public ApiResponse create(@WeaverValidatedModel Idea idea, @WeaverCredentials Cr
public ApiResponse update(@WeaverValidatedModel Idea idea) {
return new ApiResponse(SUCCESS, ideaRepo.update(idea));
}

@RequestMapping("/reject")
@PreAuthorize("hasRole('SERVICE_MANAGER')")
public ApiResponse reject(@WeaverValidatedModel Idea idea) {
ApiResponse response;
if (idea.getFeedback() == null || idea.getFeedback().equals("")) {
response = new ApiResponse(INVALID, "You must provide feedback to reject an idea.");
} else {
response = new ApiResponse(SUCCESS, ideaRepo.reject(idea));
}
return response;
}

@Transactional
@RequestMapping("/remove")
Expand Down
34 changes: 33 additions & 1 deletion src/main/java/edu/tamu/app/model/Idea.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ public class Idea extends AbstractIdea {
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private IdeaState state;

@Column(nullable = true)
private String feedback;

@Column(nullable = true)
private String email;

@ManyToOne(fetch = EAGER, cascade = { CascadeType.REFRESH, CascadeType.DETACH }, optional = true)
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, scope = FeatureProposal.class, property = "id")
Expand All @@ -43,8 +49,13 @@ public Idea(String title, String description) {
this.state = IdeaState.WAITING_ON_REVIEW;
}

public Idea(String title, String description, String email) {
this(title, description);
setEmail(email);
}

public Idea(ServiceRequest serviceRequest) {
this(serviceRequest.getTitle(), serviceRequest.getDescription());
this(serviceRequest.getTitle(), serviceRequest.getDescription(), serviceRequest.getEmail());
}

public Idea(String title, String description, User author) {
Expand All @@ -56,6 +67,11 @@ public Idea(String title, String description, User author, Service service) {
super(title, description, author, service);
this.state = IdeaState.WAITING_ON_REVIEW;
}

public Idea(String title, String description, User author, Service service, String email) {
this(title, description, author, service);
this.email = email;
}

public IdeaState getState() {
return state;
Expand All @@ -65,6 +81,22 @@ public void setState(IdeaState state) {
this.state = state;
}

public String getFeedback() {
return feedback;
}

public void setFeedback(String feedback) {
this.feedback = feedback;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public FeatureProposal getFeatureProposal() {
return featureProposal;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ public interface IdeaRepoCustom {

public void delete(Idea idea);

public Idea reject(Idea idea);

}
22 changes: 22 additions & 0 deletions src/main/java/edu/tamu/app/model/repo/impl/IdeaRepoImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,35 @@

import java.util.Optional;

import javax.mail.MessagingException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;

import edu.tamu.app.enums.IdeaState;
import edu.tamu.app.exception.UserNotFoundException;
import edu.tamu.app.model.Idea;
import edu.tamu.app.model.User;
import edu.tamu.app.model.repo.IdeaRepo;
import edu.tamu.app.model.repo.UserRepo;
import edu.tamu.app.model.repo.custom.IdeaRepoCustom;
import edu.tamu.weaver.auth.model.Credentials;
import edu.tamu.weaver.email.service.EmailSender;
import edu.tamu.weaver.response.ApiResponse;

public class IdeaRepoImpl implements IdeaRepoCustom {

private static final String REJECTION_SUBJECT = "Your idea has been rejected.";

@Autowired
private UserRepo userRepo;

@Autowired
private IdeaRepo ideaRepo;

@Autowired
private EmailSender emailService;

@Autowired
private SimpMessagingTemplate simpMessagingTemplate;

Expand Down Expand Up @@ -52,4 +61,17 @@ public void delete(Idea idea) {
simpMessagingTemplate.convertAndSend("/channel/ideas/delete", new ApiResponse(SUCCESS, idea.getId()));
}

public Idea reject(Idea idea) {
idea.setState(IdeaState.REJECTED);
String body = "Your idea " + idea.getTitle() + ", for " + idea.getService().getName() + ", has been rejected for the following reason:\n" + idea.getFeedback();
try {
if (idea.getEmail() != null && !idea.getEmail().isEmpty()) {
emailService.sendEmail(idea.getEmail(), REJECTION_SUBJECT, body);
}

} catch (MessagingException e) {
e.printStackTrace();
}
return ideaRepo.update(idea);
}
}
17 changes: 16 additions & 1 deletion src/main/java/edu/tamu/app/model/request/ServiceRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,20 @@ public class ServiceRequest extends AbstractRequest {

private Long service;

private String email;

public ServiceRequest() {
super();
}

public ServiceRequest(RequestType type, String title, String description, Long service) {
super(type, title, description);
this.service = service;
setService(service);
}

public ServiceRequest(RequestType type, String title, String description, Long service, String email) {
this(type, title, description, service);
setEmail(email);
}

public Long getService() {
Expand All @@ -23,4 +30,12 @@ public void setService(Long service) {
this.service = service;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

}
22 changes: 22 additions & 0 deletions src/test/java/edu/tamu/app/controller/IdeaControllerTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package edu.tamu.app.controller;

import static edu.tamu.weaver.response.ApiStatus.INVALID;
import static edu.tamu.weaver.response.ApiStatus.SUCCESS;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
Expand All @@ -23,6 +24,7 @@
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import edu.tamu.app.enums.IdeaState;
import edu.tamu.app.enums.Status;
import edu.tamu.app.exception.UserNotFoundException;
import edu.tamu.app.model.Idea;
Expand Down Expand Up @@ -51,12 +53,15 @@ public class IdeaControllerTest {
private static final String TEST_MODIFIED_IDEA_TITLE = "Modified Idea Title";
private static final String TEST_MODIFIED_IDEA_DESCRIPTION = "Modified Idea Description";
private static final String TEST_SERVICE_NAME = "Test Service";
private static final String TEST_FEEDBACK = "Test Rejection Feedback";

private static Service TEST_SERVICE = new Service(TEST_SERVICE_NAME, Status.UP, false, true, true, "", "");
private static Idea TEST_IDEA1 = new Idea(TEST_IDEA_TITLE1, TEST_IDEA_DESCRIPTION1, TEST_USER1);
private static Idea TEST_IDEA2 = new Idea(TEST_IDEA_TITLE2, TEST_IDEA_DESCRIPTION2, TEST_USER1);
private static Idea TEST_IDEA3 = new Idea(TEST_IDEA_TITLE3, TEST_IDEA_DESCRIPTION3, TEST_USER1);
private static Idea TEST_MODIFIED_IDEA = new Idea(TEST_MODIFIED_IDEA_TITLE, TEST_MODIFIED_IDEA_DESCRIPTION, TEST_USER2, TEST_SERVICE);
private static Idea ideaWtihFeedback = new Idea(TEST_IDEA_TITLE1, TEST_IDEA_DESCRIPTION1, TEST_USER1);
private Idea rejectedIdea = new Idea(TEST_IDEA_TITLE1, TEST_IDEA_DESCRIPTION1, TEST_USER1);
private static List<Idea> mockIdeaList = new ArrayList<Idea>(Arrays.asList(new Idea[] { TEST_IDEA1, TEST_IDEA2, TEST_IDEA3 }));
private static Page<Idea> mockPageableIdeaList = new PageImpl<Idea>(Arrays.asList(new Idea[] { TEST_IDEA1, TEST_IDEA2, TEST_IDEA3 }));

Expand Down Expand Up @@ -85,6 +90,8 @@ public class IdeaControllerTest {
@Before
@SuppressWarnings("unchecked")
public void setup() throws UserNotFoundException {
rejectedIdea.setState(IdeaState.REJECTED);
ideaWtihFeedback.setFeedback(TEST_FEEDBACK);
MockitoAnnotations.initMocks(this);
when(credentials.getUin()).thenReturn("123456789");
when(userRepo.findByUsername(any(String.class))).thenReturn(Optional.of(user));
Expand All @@ -93,6 +100,7 @@ public void setup() throws UserNotFoundException {
when(ideaRepo.findOne(any(Long.class))).thenReturn(TEST_IDEA1);
when(ideaRepo.create(any(Idea.class), any(Credentials.class))).thenReturn(TEST_IDEA1);
when(ideaRepo.update(any(Idea.class))).thenReturn(TEST_MODIFIED_IDEA);
when(ideaRepo.reject(TEST_IDEA1)).thenReturn(rejectedIdea);
when(serviceRepo.findOne(any(Long.class))).thenReturn(TEST_SERVICE);
doNothing().when(ideaRepo).delete(any(Idea.class));
doNothing().when(ideaRepo).delete(any(Idea.class));
Expand Down Expand Up @@ -132,6 +140,20 @@ public void testUpdate() {
assertEquals("Notification Author was not properly updated", TEST_MODIFIED_IDEA.getAuthor(), idea.getAuthor());
}

@Test
public void testReject() {
response = ideaController.reject(ideaWtihFeedback);
assertEquals("Not successful at rejecting idea", SUCCESS, response.getMeta().getStatus());
Idea idea = (Idea) response.getPayload().get("Idea");
assertEquals("State was not set to Rejected", rejectedIdea.getState(), idea.getState());
}

@Test
public void testInvalidReject() {
response = ideaController.reject(TEST_IDEA1);
assertEquals("Idea without feedback was successfull", INVALID, response.getMeta().getStatus());
}

@Test
public void testRemove() {
response = ideaController.remove(TEST_MODIFIED_IDEA);
Expand Down
18 changes: 17 additions & 1 deletion src/test/java/edu/tamu/app/model/IdeaTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.springframework.test.context.junit4.SpringRunner;

import edu.tamu.app.StatusApplication;
import edu.tamu.app.enums.IdeaState;
import edu.tamu.app.enums.Role;
import edu.tamu.app.enums.Status;
import edu.tamu.app.exception.UserNotFoundException;
Expand All @@ -35,6 +36,7 @@ public class IdeaTest {
private static final String TEST_ALTERNATIVE_SERVICE_NAME = "Different Service Name";
private static final String TEST_IDEA_DESCRIPTION = "Test Idea Description";
private static final String TEST_ALTERNATIVE_IDEA_DESCRIPTION = "Alternative Idea Description";
private static final String TEST_IDEA_EMAIL = "aggiejack@mailinator.com";
private static final Boolean TEST_IS_AUTO = false;
private static final Boolean TEST_IS_PUBLIC = true;
private static final Boolean TEST_ON_SHORT_LIST = true;
Expand Down Expand Up @@ -78,7 +80,7 @@ public void setUp() throws UserNotFoundException {
testUser = userRepo.create(TEST_CREDENTIALS.getUin(), TEST_CREDENTIALS.getEmail(), TEST_CREDENTIALS.getFirstName(), TEST_CREDENTIALS.getLastName(), Role.valueOf(TEST_CREDENTIALS.getRole()));
service1 = serviceRepo.create(new Service(TEST_SERVICE_NAME, TEST_SERVICE_STATUS, TEST_IS_AUTO, TEST_IS_PUBLIC, TEST_ON_SHORT_LIST, TEST_SERVICE_URL, TEST_DESCRIPTION));
service2 = serviceRepo.create(new Service(TEST_ALTERNATIVE_SERVICE_NAME, TEST_SERVICE_STATUS, TEST_IS_AUTO, TEST_IS_PUBLIC, TEST_ON_SHORT_LIST, TEST_SERVICE_URL, TEST_DESCRIPTION));
testIdea = ideaRepo.create(new Idea(TEST_IDEA_TITLE, TEST_IDEA_DESCRIPTION, testUser, service1), TEST_CREDENTIALS);
testIdea = ideaRepo.create(new Idea(TEST_IDEA_TITLE, TEST_IDEA_DESCRIPTION, testUser, service1, TEST_IDEA_EMAIL), TEST_CREDENTIALS);
testFeatureProposal = featureProposalRepo.create(new FeatureProposal(TEST_FEATURE_PROPOSAL_TITLE, TEST_FEATURE_PROPOSAL_DESCRIPTION, testUser, service1), TEST_CREDENTIALS);
}

Expand Down Expand Up @@ -144,6 +146,20 @@ public void testUpdateFeatureProposal() throws UserNotFoundException {
assertEquals("Feature proposal does not have idea", idea, testFeatureProposal.getIdeas().get(0));
}

@Test
public void testReject() throws UserNotFoundException {
Idea idea = ideaRepo.create(testIdea, TEST_CREDENTIALS);
idea = ideaRepo.reject(idea);

assertEquals("Idea was not rejected", IdeaState.REJECTED, idea.getState());
}

@Test
public void testRejectException() {
Idea idea = new Idea(TEST_IDEA_TITLE, TEST_IDEA_DESCRIPTION, testUser, service1);
ideaRepo.reject(idea);
}

@Test
public void testTimestampSetOnCreate() throws UserNotFoundException {
Idea Idea = ideaRepo.create(testIdea, TEST_CREDENTIALS);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package edu.tamu.app.model.impl;
package edu.tamu.app.model;

import static org.junit.Assert.assertEquals;

Expand Down
37 changes: 37 additions & 0 deletions src/test/java/edu/tamu/app/model/request/ServiceRequestTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package edu.tamu.app.model.request;

import static org.junit.Assert.assertEquals;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringRunner;

import edu.tamu.app.model.request.AbstractRequest.RequestType;

@RunWith(SpringRunner.class)
public class ServiceRequestTest {

private static final RequestType TEST_REQUEST_TYPE = RequestType.FEATURE;
private static final String TEST_TITLE = "Test Request title";
private static final String TEST_DESCRIPTION = "Test Request Description";
private static final Long TEST_SERVICE_ID = 1L;
private static final String TEST_EMAIL = "aggiejack@mailinator.com";

@Test
public void testConstructors() {
// Constructor without email
ServiceRequest serviceRequest = new ServiceRequest(TEST_REQUEST_TYPE, TEST_TITLE, TEST_DESCRIPTION, TEST_SERVICE_ID);
assertEquals("Type was not set", RequestType.FEATURE, serviceRequest.getType());
assertEquals("Title was not set", TEST_TITLE, serviceRequest.getTitle());
assertEquals("Description was not set", TEST_DESCRIPTION, serviceRequest.getDescription());
assertEquals("Service ID was not set", TEST_SERVICE_ID, serviceRequest.getService());

// Constructor with email
ServiceRequest serviceRequestWithEmail = new ServiceRequest(TEST_REQUEST_TYPE, TEST_TITLE, TEST_DESCRIPTION, TEST_SERVICE_ID, TEST_EMAIL);
assertEquals("Type was not set", RequestType.FEATURE, serviceRequestWithEmail.getType());
assertEquals("Title was not set", TEST_TITLE, serviceRequestWithEmail.getTitle());
assertEquals("Description was not set", TEST_DESCRIPTION, serviceRequestWithEmail.getDescription());
assertEquals("Service ID was not set", TEST_SERVICE_ID, serviceRequestWithEmail.getService());
assertEquals("Email was not set", TEST_EMAIL, serviceRequestWithEmail.getEmail());
}
}