Skip to content

Commit

Permalink
Corrected hour format of the generated markdown and updated the Repor…
Browse files Browse the repository at this point in the history
…tDataController test.
  • Loading branch information
ocielliottc committed Dec 17, 2024
1 parent e3c3e91 commit 819a746
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -356,11 +356,12 @@ private void compensationHistory(ReportDataCollation data, StringBuilder sb) {
.append(new Heading("Base Compensation (annual or hourly)", 3))
.append("\n");
List<String> list = new ArrayList<>();
final String compFormat = "%.2f";
for (CompensationHistory.Compensation comp : compBase) {
String value = comp.amount();
try {
double val = Double.parseDouble(value);
value = String.format("%.2f", val);
value = String.format(compFormat, val);
} catch (Exception e) {
}
list.add(formatDate(comp.startDate()) + " - $" + value);
Expand All @@ -384,13 +385,14 @@ private void employeeHours(ReportDataCollation data, StringBuilder sb) {
sb.append(new Heading("Employee Hours", 2)).append("\n");
List<String> list = new ArrayList<>();
ReportHours hours = data.getReportHours();
final String hourFormat = "%.2f";
list.add("Contribution Hours: " +
String.format("%f", hours.contributionHours()));
list.add("PTO Hours: " + String.format("%f", hours.ptoHours()));
String.format(hourFormat, hours.contributionHours()));
list.add("PTO Hours: " + String.format(hourFormat, hours.ptoHours()));
list.add("Overtime Hours: " +
String.format("%f", hours.overtimeHours()));
String.format(hourFormat, hours.overtimeHours()));
list.add("Billable Utilization: " +
String.format("%f", hours.billableUtilization()));
String.format(hourFormat, hours.billableUtilization()));
sb.append(new UnorderedList<>(list)).append("\n\n");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.objectcomputing.checkins.services.file.FileServices;

import io.micronaut.http.MediaType;
import io.micronaut.http.HttpStatus;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Post;
import io.micronaut.http.annotation.Get;
Expand Down Expand Up @@ -122,8 +123,8 @@ private String uploadHelper(ReportDataServices.DataType dataType,

@Get(uri="/generate")
@RequiredPermission(Permission.CAN_CREATE_MERIT_REPORT)
public void generate(@NotNull List<UUID> memberIds,
@NotNull UUID reviewPeriodId) {
public HttpStatus generate(@NotNull List<UUID> memberIds,
@NotNull UUID reviewPeriodId) {
MarkdownGeneration markdown =
new MarkdownGeneration(reportDataServices,
kudosRepository,
Expand All @@ -137,5 +138,6 @@ public void generate(@NotNull List<UUID> memberIds,
employeeHoursServices,
fileServices);
markdown.upload(memberIds, reviewPeriodId);
return HttpStatus.OK;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.objectcomputing.checkins.services.reports;

/*************************************************************************
*
* This class is here due to the fact that the ReportDataController now
* references the FileServices. The real FileServicesImpl requires the
* GoogleApiAccess class that does not exist during testing.
*
* This replacement class does not require that and can help us test the
* output of the MarkdownGeneration class.
*
************************************************************************/

import com.objectcomputing.checkins.services.file.FileInfoDTO;
import com.objectcomputing.checkins.services.file.FileServices;
import com.objectcomputing.checkins.services.file.FileServicesImpl;

import io.micronaut.http.multipart.CompletedFileUpload;

import java.io.File;
import java.util.Set;
import java.util.HashSet;
import java.util.UUID;

import jakarta.inject.Singleton;
import io.micronaut.context.env.Environment;
import io.micronaut.context.annotation.Replaces;
import io.micronaut.context.annotation.Requires;

@Singleton
@Replaces(FileServicesImpl.class)
@Requires(env = Environment.TEST)
public class FileServicesImplReplacement implements FileServices {
public String documentName = "";
public String documentText = "";

public Set<FileInfoDTO> findFiles(UUID checkInId) {
return new HashSet<FileInfoDTO>();
}

public File downloadFiles(String uploadDocId) {
return null;
}

public FileInfoDTO uploadFile(UUID checkInID, CompletedFileUpload file) {
return new FileInfoDTO();
}

public FileInfoDTO uploadDocument(String directory,
String name, String text) {
documentName = name;
documentText = text;
return new FileInfoDTO();
}

public boolean deleteFile(String uploadDocId) {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package com.objectcomputing.checkins.services.reports;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.objectcomputing.checkins.services.kudos.Kudos;
import com.objectcomputing.checkins.services.TestContainersSuite;
import com.objectcomputing.checkins.services.fixture.KudosFixture;
Expand All @@ -22,6 +18,8 @@
import com.objectcomputing.checkins.services.feedback_template.template_question.TemplateQuestion;
import com.objectcomputing.checkins.services.employee_hours.EmployeeHours;

import io.micronaut.core.util.StringUtils;
import io.micronaut.context.annotation.Property;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.client.HttpClient;
import io.micronaut.http.client.annotation.Client;
Expand All @@ -34,6 +32,7 @@

import java.io.File;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE;
import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE;
Expand All @@ -44,12 +43,16 @@
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

@Property(name = "replace.fileservicesimpl", value = StringUtils.TRUE)
class ReportDataControllerTest extends TestContainersSuite implements MemberProfileFixture, RoleFixture, KudosFixture, ReviewPeriodFixture, FeedbackTemplateFixture, FeedbackRequestFixture, TemplateQuestionFixture, FeedbackAnswerFixture, EmployeeHoursFixture {

@Inject
@Client("/services/report/data")
HttpClient client;

@Inject
private FileServicesImplReplacement fileServices;

private EmployeeHours employeeHours;
private FeedbackTemplate feedbackTemplate;
private ReviewPeriod reviewPeriod;
Expand All @@ -58,6 +61,7 @@ class ReportDataControllerTest extends TestContainersSuite implements MemberProf
private TemplateQuestion questionTwo;
private MemberProfile regular;
private MemberProfile admin;
private Kudos kudos;
private final String basePath = "src/test/java/com/objectcomputing/checkins/services/reports/";

@BeforeEach
Expand All @@ -79,7 +83,7 @@ void createRolesAndPermissions() {
saveSampleFeedbackAnswer(questionOne.getId(), feedbackRequest.getId());
saveSampleFeedbackAnswer(questionTwo.getId(), feedbackRequest.getId());

Kudos kudos = createApprovedKudos(admin.getId());
kudos = createApprovedKudos(admin.getId());
createKudosRecipient(kudos.getId(), regular.getId());

employeeHours = new EmployeeHours(regular.getEmployeeId(),
Expand All @@ -106,45 +110,27 @@ void uploadReportDataWithoutPermission() {
}

@Test
void getReportData() throws JsonProcessingException {
void processReportData() {
MemberProfile target = regular;
HttpRequest<?> request = postData(admin, ADMIN_ROLE);
final String response = client.toBlocking().retrieve(request);
assertNotNull(response);

request = HttpRequest.GET(
String.format("/?memberIds=%s&reviewPeriodId=%s",
String.format("/generate?memberIds=%s&reviewPeriodId=%s",
target.getId(),
reviewPeriod.getId().toString()))
.basicAuth(admin.getWorkEmail(), ADMIN_ROLE);
final String data = client.toBlocking().retrieve(request);
ObjectMapper objectMapper = new ObjectMapper();
assertNotNull(data);

// Perform minimal validation of returned data
JsonNode root = objectMapper.readTree(data);
assertTrue(root.isArray());
assertFalse(root.isEmpty());

ArrayNode arrayNode = (ArrayNode)root;
JsonNode first = arrayNode.get(0);
assertNotNull(first.get("memberProfile"));
assertNotNull(first.get("kudos"));
assertNotNull(first.get("compensationHistory"));
assertNotNull(first.get("currentInformation"));
assertNotNull(first.get("positionHistory"));
assertNotNull(first.get("selfReviews"));
assertNotNull(first.get("reviews"));
assertNotNull(first.get("feedback"));
assertNotNull(first.get("hours"));

validateReportData(first, target);
client.toBlocking().exchange(request);

validateReportData(fileServices.documentName,
fileServices.documentText, target);
}

@Test
void getReportDataWithoutPermission() {
void processReportDataWithoutPermission() {
final HttpRequest<?> request = HttpRequest.GET(
String.format("/?memberIds=%s&reviewPeriodId=%s",
String.format("/generate?memberIds=%s&reviewPeriodId=%s",
regular.getId(),
reviewPeriod.getId()))
.basicAuth(regular.getWorkEmail(), MEMBER_ROLE);
Expand All @@ -168,54 +154,43 @@ HttpRequest<?> postData(MemberProfile user, String role) {
.contentType(MULTIPART_FORM_DATA);
}

void validateReportData(JsonNode node, MemberProfile user) {
final String memberId = user.getId().toString();
private String formatDate(LocalDate date) {
return date.format(DateTimeFormatter.ofPattern("MM/dd/yyyy"));
}

void validateReportData(String filename, String text, MemberProfile user) {
assertEquals(user.getWorkEmail(), filename);

// Review Period
assertTrue(text.contains(
formatDate(reviewPeriod.getPeriodStartDate().toLocalDate())));
assertTrue(text.contains(
formatDate(reviewPeriod.getPeriodEndDate().toLocalDate())));

// Member Info
assertEquals(memberId, node.get("memberId").asText());
JsonNode profile = node.get("memberProfile");
assertEquals(user.getFirstName(), profile.get("firstName").asText());
assertEquals(user.getLastName(), profile.get("lastName").asText());
assertEquals(user.getTitle(), profile.get("title").asText());
assertTrue(text.contains(user.getFirstName()));
assertTrue(text.contains(user.getLastName()));
assertTrue(text.contains(user.getTitle()));

// Kudos
ArrayNode kudos = (ArrayNode)node.get("kudos");
assertEquals(1, kudos.size());
assertEquals("Default Kudos", kudos.get(0).get("message").asText());

// Compensation History
ArrayNode comp = (ArrayNode)node.get("compensationHistory");
assertEquals(10, comp.size());
assertEquals(memberId, comp.get(0).get("memberId").asText());
assertTrue(comp.get(0).get("amount").asDouble() > 0);
assertFalse(comp.get(9).get("totalComp").asText().isEmpty());

// Current Information
JsonNode curr = node.get("currentInformation");
assertEquals(memberId, curr.get("memberId").asText());
assertTrue(curr.get("salary").asDouble() > 0);
assertEquals("$90000 - $150000", curr.get("range").asText());
assertEquals("$89000 - $155000", curr.get("nationalRange").asText());

// Position History
ArrayNode pos = (ArrayNode)node.get("positionHistory");
assertEquals(3, pos.size());
assertEquals(memberId, pos.get(2).get("memberId").asText());
assertEquals("Software Engineer", pos.get(2).get("title").asText());
assertTrue(text.contains(kudos.getMessage()));

// Feedback
ArrayNode feedback = (ArrayNode)node.get("feedback");
assertEquals(1, feedback.size());
ArrayNode answers = (ArrayNode)feedback.get(0).get("answers");
assertEquals(2, answers.size());
assertEquals("TEXT", answers.get(0).get("type").asText());
assertEquals(1, answers.get(0).get("number").asInt());
assertTrue(text.contains(feedbackTemplate.getTitle()));
assertTrue(text.contains(questionOne.getQuestion()));
assertTrue(text.contains(questionTwo.getQuestion()));
assertTrue(text.contains(
formatDate(feedbackRequest.getSubmitDate())));

// Hours
JsonNode hours = node.get("hours");
assertEquals(employeeHours.getContributionHours(), hours.get("contributionHours").asDouble(), 0.0);
assertEquals(employeeHours.getPtoHours(), hours.get("ptoHours").asDouble(), 0.0);
assertEquals(employeeHours.getOvertimeWorked(), hours.get("overtimeHours").asDouble(), 0.0);
assertEquals(employeeHours.getBillableUtilization(), hours.get("billableUtilization").asDouble(), 0.0);
final String format = "%.2f";
assertTrue(text.contains(
String.format(format, employeeHours.getContributionHours())));
assertTrue(text.contains(
String.format(format, employeeHours.getPtoHours())));
assertTrue(text.contains(
String.format(format, employeeHours.getOvertimeWorked())));
assertTrue(text.contains(
String.format(format, employeeHours.getBillableUtilization())));
}
}

0 comments on commit 819a746

Please sign in to comment.