From 8469964c335b8fc56306215710c8cc54c74fa402 Mon Sep 17 00:00:00 2001 From: prit-cgi Date: Tue, 13 Dec 2022 16:41:38 -0400 Subject: [PATCH 1/5] 8195 Add SPG to Audit Report --- .../hnweb/controller/AuditController.java | 26 ++- .../model/rest/auditreport/AuditRecord.java | 10 + .../rest/auditreport/AuditReportRequest.java | 10 + .../hnweb/persistence/entity/Transaction.java | 22 +- .../AffectedPartyPageableRepository.java | 36 ++-- .../gov/hlth/hnweb/security/SecurityUtil.java | 134 ++++++++---- .../bc/gov/hlth/hnweb/security/UserInfo.java | 17 +- .../gov/hlth/hnweb/service/AuditService.java | 141 +++++++------ .../hnweb/controller/AuditControllerTest.java | 192 +++++++++++------- frontend/src/views/reports/AuditReporting.vue | 19 ++ .../e2e/pages/reports/AuditReportingPage.js | 1 + .../e2e/tests/reports/AuditReportingTest.js | 37 ++-- 12 files changed, 416 insertions(+), 229 deletions(-) diff --git a/backend/src/main/java/ca/bc/gov/hlth/hnweb/controller/AuditController.java b/backend/src/main/java/ca/bc/gov/hlth/hnweb/controller/AuditController.java index 987d843c..120aacbf 100644 --- a/backend/src/main/java/ca/bc/gov/hlth/hnweb/controller/AuditController.java +++ b/backend/src/main/java/ca/bc/gov/hlth/hnweb/controller/AuditController.java @@ -42,9 +42,9 @@ @RequestMapping("/audit") @RestController public class AuditController extends BaseController { - + private static final String AUDIT_REPORT_PREFIX = "auditreport_"; - + private static final String AUDIT_REPORT_EXTENSION = ".csv"; private static final Logger logger = LoggerFactory.getLogger(AuditController.class); @@ -63,14 +63,15 @@ public class AuditController extends BaseController { public ResponseEntity getAuditReport(@Valid @RequestBody AuditReportRequest auditReportRequest, HttpServletRequest request) { - Page pageable = auditService.getAffectedParties( - auditReportRequest.getTransactionTypes(), auditReportRequest.getOrganizations(), - auditReportRequest.getUserId(), auditReportRequest.getStartDate(), auditReportRequest.getEndDate(), - auditReportRequest.getPage(), auditReportRequest.getRows(), auditReportRequest.getSortField(), auditReportRequest.getSortDirection()); + Page pageable = auditService.getAffectedParties(auditReportRequest.getTransactionTypes(), + auditReportRequest.getOrganizations(), auditReportRequest.getSpgRoles(), auditReportRequest.getUserId(), + auditReportRequest.getStartDate(), auditReportRequest.getEndDate(), auditReportRequest.getPage(), + auditReportRequest.getRows(), auditReportRequest.getSortField(), auditReportRequest.getSortDirection()); List auditReport = convertReport(pageable.getContent()); int first = auditReportRequest.getPage() * auditReportRequest.getRows(); - logger.info("Returning {}-{} of {} audit records", first, first + pageable.getNumberOfElements(), pageable.getTotalElements()); + logger.info("Returning {}-{} of {} audit records", first, first + pageable.getNumberOfElements(), + pageable.getTotalElements()); AuditReportResponse auditReportingResponse = new AuditReportResponse(); auditReportingResponse.setRecords(auditReport); @@ -93,9 +94,10 @@ public ResponseEntity> getOrganizations() { ResponseEntity> responseEntity = ResponseEntity.ok(organizations); return responseEntity; } - + /** * Retrieves audit records for download + * * @param auditReportRequest * @param request * @return @@ -106,7 +108,9 @@ public ResponseEntity downloadAuditReport(@Valid @RequestBody AuditRep List affectedPartiesForDownload = auditService.getAffectedPartiesForDownload( auditReportRequest.getTransactionTypes(), auditReportRequest.getOrganizations(), - auditReportRequest.getUserId(), auditReportRequest.getStartDate(), auditReportRequest.getEndDate(), auditReportRequest.getSortField(), auditReportRequest.getSortDirection()); + auditReportRequest.getSpgRoles(), auditReportRequest.getUserId(), auditReportRequest.getStartDate(), + auditReportRequest.getEndDate(), auditReportRequest.getSortField(), + auditReportRequest.getSortDirection()); List auditReport = convertReport(affectedPartiesForDownload); logger.info("Number of records returned for download : {}", auditReport.size()); @@ -126,6 +130,7 @@ private List convertReport(List affectedParties) { affectedParties.forEach(affectedParty -> { AuditRecord model = new AuditRecord(); model.setOrganization(affectedParty.getTransaction().getOrganization()); + model.setSpgRole(affectedParty.getTransaction().getSpgRole()); model.setTransactionId(affectedParty.getTransaction().getTransactionId().toString()); model.setType(affectedParty.getTransaction().getType()); model.setUserId(affectedParty.getTransaction().getUserId()); @@ -140,7 +145,8 @@ private List convertReport(List affectedParties) { } private List convertOrganization(List organizations) { - return organizations.stream().filter(org -> StringUtils.isNotBlank(org.getOrganization())).map(org -> org.getOrganization()).collect(Collectors.toList()); + return organizations.stream().filter(org -> StringUtils.isNotBlank(org.getOrganization())) + .map(org -> org.getOrganization()).collect(Collectors.toList()); } private LocalDateTime convertDate(Date date) { diff --git a/backend/src/main/java/ca/bc/gov/hlth/hnweb/model/rest/auditreport/AuditRecord.java b/backend/src/main/java/ca/bc/gov/hlth/hnweb/model/rest/auditreport/AuditRecord.java index 0eb60ae2..07d5de2e 100644 --- a/backend/src/main/java/ca/bc/gov/hlth/hnweb/model/rest/auditreport/AuditRecord.java +++ b/backend/src/main/java/ca/bc/gov/hlth/hnweb/model/rest/auditreport/AuditRecord.java @@ -18,6 +18,16 @@ public class AuditRecord { private String transactionId; + private String spgRole; + + public String getSpgRole() { + return spgRole; + } + + public void setSpgRole(String spgRole) { + this.spgRole = spgRole; + } + public String getType() { return type; } diff --git a/backend/src/main/java/ca/bc/gov/hlth/hnweb/model/rest/auditreport/AuditReportRequest.java b/backend/src/main/java/ca/bc/gov/hlth/hnweb/model/rest/auditreport/AuditReportRequest.java index 4eeea223..464b2b4d 100644 --- a/backend/src/main/java/ca/bc/gov/hlth/hnweb/model/rest/auditreport/AuditReportRequest.java +++ b/backend/src/main/java/ca/bc/gov/hlth/hnweb/model/rest/auditreport/AuditReportRequest.java @@ -10,6 +10,8 @@ public class AuditReportRequest { private List organizations; private List transactionTypes; + + private List spgRoles; private LocalDate startDate; @@ -17,6 +19,14 @@ public class AuditReportRequest { private Integer page = 0; + public List getSpgRoles() { + return spgRoles; + } + + public void setSpgRoles(List spgRoles) { + this.spgRoles = spgRoles; + } + private Integer rows = 10; private String sortField; diff --git a/backend/src/main/java/ca/bc/gov/hlth/hnweb/persistence/entity/Transaction.java b/backend/src/main/java/ca/bc/gov/hlth/hnweb/persistence/entity/Transaction.java index d6c08eff..4da13eab 100644 --- a/backend/src/main/java/ca/bc/gov/hlth/hnweb/persistence/entity/Transaction.java +++ b/backend/src/main/java/ca/bc/gov/hlth/hnweb/persistence/entity/Transaction.java @@ -62,6 +62,21 @@ public class Transaction { @Column(name = "organization") private String organization; + /** + * SPG of the user performing the transaction + */ + @Basic + @Column(name = "spg_role") + private String spgRole; + + public String getSpgRole() { + return spgRole; + } + + public void setSpgRole(String spgRole) { + this.spgRole = spgRole; + } + /** * ID of the user that initiated the transaction */ @@ -139,7 +154,7 @@ public Date getStartTime() { public void setStartTime(Date startTime) { this.startTime = startTime; } - + @PrePersist public void prePersist() { if (startTime == null) { @@ -216,8 +231,9 @@ public boolean equals(Object obj) { @Override public String toString() { - return "Transaction [transactionId=" + transactionId + ", type=" + type + ", sessionId=" + sessionId + ", server=" + server - + ", sourceIp=" + sourceIp + ", organization=" + organization + ", userId=" + userId + ", startTime=" + startTime + "]"; + return "Transaction [transactionId=" + transactionId + ", type=" + type + ", sessionId=" + sessionId + + ", server=" + server + ", sourceIp=" + sourceIp + ", organization=" + organization + ", userId=" + + userId + ", startTime=" + startTime + "]"; } } \ No newline at end of file diff --git a/backend/src/main/java/ca/bc/gov/hlth/hnweb/persistence/repository/AffectedPartyPageableRepository.java b/backend/src/main/java/ca/bc/gov/hlth/hnweb/persistence/repository/AffectedPartyPageableRepository.java index 9a6d2692..efdac9a3 100644 --- a/backend/src/main/java/ca/bc/gov/hlth/hnweb/persistence/repository/AffectedPartyPageableRepository.java +++ b/backend/src/main/java/ca/bc/gov/hlth/hnweb/persistence/repository/AffectedPartyPageableRepository.java @@ -14,22 +14,28 @@ public interface AffectedPartyPageableRepository extends PagingAndSortingRepository { - @Query("SELECT af from AffectedParty af where " - +"(COALESCE(:organizations, null) is null or af.transaction.organization IN (:organizations)) and " - +"(COALESCE(:type, null) is null or af.transaction.type IN (:type)) and " - +"(COALESCE(:userId, null) is null or :userId = '' or upper(af.transaction.userId)= upper(:userId)) and " - +"(af.direction=:direction) and " - +"(date_trunc('day', af.transaction.startTime) between :startDate and :endDate) ") + @Query("SELECT af from AffectedParty af where " + + "(COALESCE(:organizations, null) is null or af.transaction.organization IN (:organizations)) and " + + "(COALESCE(:type, null) is null or af.transaction.type IN (:type)) and " + + "(COALESCE(:spgRoles, null) is null or af.transaction.spgRole IN (:spgRoles)) and " + + "(COALESCE(:userId, null) is null or :userId = '' or upper(af.transaction.userId)= upper(:userId)) and " + + "(af.direction=:direction) and " + + "(date_trunc('day', af.transaction.startTime) between :startDate and :endDate) ") Page findByTransactionAndDirection(@Param("type") List type, - @Param("organizations") List organizations, @Param("userId") String userId, @Param("direction") String direction, @Param("startDate") Date startDate, @Param("endDate") Date endDate, Pageable pageable); - - @Query("SELECT af from AffectedParty af where " - +"(COALESCE(:organizations, null) is null or af.transaction.organization IN (:organizations)) and " - +"(COALESCE(:type, null) is null or af.transaction.type IN (:type)) and " - +"(COALESCE(:userId, null) is null or :userId = '' or upper(af.transaction.userId)= upper(:userId)) and " - +"(af.direction=:direction) and " - +"(date_trunc('day', af.transaction.startTime) between :startDate and :endDate) ") + @Param("organizations") List organizations, @Param("spgRoles") List spgRoles, + @Param("userId") String userId, @Param("direction") String direction, @Param("startDate") Date startDate, + @Param("endDate") Date endDate, Pageable pageable); + + @Query("SELECT af from AffectedParty af where " + + "(COALESCE(:organizations, null) is null or af.transaction.organization IN (:organizations)) and " + + "(COALESCE(:type, null) is null or af.transaction.type IN (:type)) and " + + "(COALESCE(:spgRoles, null) is null or af.transaction.spgRole IN (:spgRoles)) and " + + "(COALESCE(:userId, null) is null or :userId = '' or upper(af.transaction.userId)= upper(:userId)) and " + + "(af.direction=:direction) and " + + "(date_trunc('day', af.transaction.startTime) between :startDate and :endDate) ") List findByTransactionAndDirection(@Param("type") List type, - @Param("organizations") List organizations, @Param("userId") String userId, @Param("direction") String direction, @Param("startDate") Date startDate, @Param("endDate") Date endDate, Sort sort); + @Param("organizations") List organizations, @Param("spgRoles") List spgRoles, + @Param("userId") String userId, @Param("direction") String direction, @Param("startDate") Date startDate, + @Param("endDate") Date endDate, Sort sort); } diff --git a/backend/src/main/java/ca/bc/gov/hlth/hnweb/security/SecurityUtil.java b/backend/src/main/java/ca/bc/gov/hlth/hnweb/security/SecurityUtil.java index 74d73f27..5107385e 100644 --- a/backend/src/main/java/ca/bc/gov/hlth/hnweb/security/SecurityUtil.java +++ b/backend/src/main/java/ca/bc/gov/hlth/hnweb/security/SecurityUtil.java @@ -7,6 +7,7 @@ import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; @@ -26,80 +27,131 @@ public class SecurityUtil { private static final String CLAIM_RESOURCE_ACCESS = "resource_access"; private static final String CLAIM_SESSION_STATE = "session_state"; public static final String CLAIM_USERNAME = "preferred_username"; - private static final String CLAIM_SUB = "sub"; //the Subject claim identifies the principal that is the subject of the JWT + private static final String CLAIM_SUB = "sub"; // the Subject claim identifies the principal that is the subject of + // the JWT public static final String CLAIM_ORGANIZATION = "org_details"; - + private static final String ORGANIZATION_ID = "id"; - + private static final String USER_ROLES = "roles"; - private static String KEYCLOAK_CLIENT; - - @Value("${spring.security.oauth2.resourceserver.jwt.audience}") - private void setKeycloakClientStatic(String keycloakClient){ - SecurityUtil.KEYCLOAK_CLIENT = keycloakClient; - } + private static String KEYCLOAK_CLIENT; + + private static SecurityProperties securityProperties; + + @Autowired + public void setSecurityProperties(SecurityProperties properties) { + SecurityUtil.securityProperties = properties; + } + + @Value("${spring.security.oauth2.resourceserver.jwt.audience}") + private void setKeycloakClientStatic(String keycloakClient) { + SecurityUtil.KEYCLOAK_CLIENT = keycloakClient; + } - public static UserInfo loadUserInfo() { + public static UserInfo loadUserInfo() { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - Jwt jwt = (Jwt)auth.getPrincipal(); - + Jwt jwt = (Jwt) auth.getPrincipal(); + UserInfo userInfo = new UserInfo(); userInfo.setOrganization(extractOrganization(jwt)); - + List roles = loadRoles(jwt); - userInfo.setRole(StringUtils.join(roles, " ")); + userInfo.setRoles(roles); userInfo.setSessionState(jwt.getClaim(CLAIM_SESSION_STATE)); userInfo.setUsername(jwt.getClaim(CLAIM_USERNAME)); userInfo.setUserId(jwt.getClaim(CLAIM_SUB)); - + return userInfo; } - + + public static String loadSPGBasedOnTask(UserInfo userInfo, TransactionType transactionType) { + Map> rolePermissions = securityProperties.getRolePermissions(); + List roles = userInfo.getRoles(); + if (roles.size() == 1) { + return roles.get(0); + } + for (String role : roles) { + List permissions = rolePermissions.get(role.toLowerCase()); + switch (transactionType) { + case ENROLL_SUBSCRIBER: + if (permissions.contains("AddPermitHolderWOPHN") || permissions.contains("AddPermitHolderWithPHN")) { + return role; + } + break; + case GET_PERSON_DETAILS: + if (permissions.contains("AddPermitHolderWithPHN")) { + return role; + } + break; + case NAME_SEARCH: + if (permissions.contains("AddPermitHolderWOPHN")) { + return role; + } + break; + case CONTRACT_INQUIRY: + if (permissions.contains("ContractInquiry") || permissions.contains("GetGroupMembersContractAddress")) { + return role; + } + break; + case GET_PATIENT_REGISTRATION: + if (permissions.contains("PatientRegistration")) { + return role; + } + break; + default: + if (permissions != null && permissions.contains(transactionType.getValue())) { + return role; + } + } + } + return "UNAUTHORIZED"; + } + private static String extractOrganization(Jwt jwt) { try { ObjectMapper mapper = new ObjectMapper(); - JsonNode node = mapper.readTree((String)jwt.getClaim(CLAIM_ORGANIZATION)); + JsonNode node = mapper.readTree((String) jwt.getClaim(CLAIM_ORGANIZATION)); return node.get(ORGANIZATION_ID).asText(); } catch (Exception e) { logger.warn("User {} does not have claim {} set", jwt.getClaim(CLAIM_USERNAME), CLAIM_ORGANIZATION); return null; } } - + @SuppressWarnings("unchecked") private static List loadRoles(Jwt jwt) { List permissions = new ArrayList<>(); - Map resourceAccesses = (Map) jwt.getClaims().get(CLAIM_RESOURCE_ACCESS); + Map resourceAccesses = (Map) jwt.getClaims().get(CLAIM_RESOURCE_ACCESS); - if (resourceAccesses == null) { - return permissions; - } + if (resourceAccesses == null) { + return permissions; + } - Map resource = (Map) resourceAccesses.get(KEYCLOAK_CLIENT); - if (resource == null) { - return permissions; - } + Map resource = (Map) resourceAccesses.get(KEYCLOAK_CLIENT); + if (resource == null) { + return permissions; + } - return (List)resource.get(USER_ROLES); + return (List) resource.get(USER_ROLES); } - + public static List loadPermissions(Jwt jwt, Map> rolePermissions) { - List roles = loadRoles(jwt); - List permissions = new ArrayList<>(); - roles.forEach(role -> { - List currentPermissions = rolePermissions.get(role.toLowerCase()); - if (currentPermissions != null) { - permissions.addAll(currentPermissions); - } else { - logger.warn("Role {} has no permissions defined.", role); - } - - }); - - return permissions; + List roles = loadRoles(jwt); + List permissions = new ArrayList<>(); + roles.forEach(role -> { + List currentPermissions = rolePermissions.get(role.toLowerCase()); + if (currentPermissions != null) { + permissions.addAll(currentPermissions); + } else { + logger.warn("Role {} has no permissions defined.", role); + } + + }); + + return permissions; } } \ No newline at end of file diff --git a/backend/src/main/java/ca/bc/gov/hlth/hnweb/security/UserInfo.java b/backend/src/main/java/ca/bc/gov/hlth/hnweb/security/UserInfo.java index 1b135aa0..c2740eee 100644 --- a/backend/src/main/java/ca/bc/gov/hlth/hnweb/security/UserInfo.java +++ b/backend/src/main/java/ca/bc/gov/hlth/hnweb/security/UserInfo.java @@ -1,5 +1,9 @@ package ca.bc.gov.hlth.hnweb.security; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; + /** * Information on the current user obtained from the JWT. */ @@ -9,6 +13,7 @@ public class UserInfo { private String organization; private String role; private String sessionState; + private List roles; public UserInfo() { super(); @@ -20,7 +25,7 @@ public UserInfo(String username, String organization, String role) { this.organization = organization; this.role = role; } - + public UserInfo(String username, String userId, String organization, String role, String sessionState) { super(); this.username = username; @@ -55,11 +60,15 @@ public void setOrganization(String organization) { } public String getRole() { - return role; + return StringUtils.join(this.roles, " "); } - public void setRole(String role) { - this.role = role; + public List getRoles() { + return roles; + } + + public void setRoles(List roles) { + this.roles = roles; } public String getSessionState() { diff --git a/backend/src/main/java/ca/bc/gov/hlth/hnweb/service/AuditService.java b/backend/src/main/java/ca/bc/gov/hlth/hnweb/service/AuditService.java index 3651e5f4..931700b6 100644 --- a/backend/src/main/java/ca/bc/gov/hlth/hnweb/service/AuditService.java +++ b/backend/src/main/java/ca/bc/gov/hlth/hnweb/service/AuditService.java @@ -62,35 +62,35 @@ public class AuditService { private static final String DEFAULT_SORT = "transaction.startTime"; private static final String LOCAL_DATE_FORMAT = "yyyy-MM-dd"; - - public static final String DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss"; - - private static final String[] HEADERS = { "Type", "Organization", "User ID", "Transaction Start Time", + + public static final String DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss"; + + private static final String[] HEADERS = { "Type", "Organization", "SPG", "User ID", "Transaction Start Time", "Affected Party ID", "Affected Party ID Type", "Transaction ID" }; private static final CSVFormat FORMAT = CSVFormat.DEFAULT.withHeader(HEADERS); @Autowired private AffectedPartyRepository affectedPartyRepository; - + @Autowired private AffectedPartyPageableRepository affectedPartyPageableRepository; - + @Autowired private EventMessageRepository eventMessageRepository; @Autowired private TransactionEventRepository transactionEventRepository; - + @Autowired private TransactionRepository transactionRepository; - + @Autowired private OrganizationRepository organizationRepository; - + /** Maps simple sort names to their JPA equivalent */ private static Map sortMap = new HashMap<>(); - + static { sortMap.put("affectedPartyId", "identifier"); sortMap.put("affectedPartyType", "identifierType"); @@ -104,7 +104,7 @@ public class AuditService { * Creates a new {@link Transaction}. * * @param sourceIP Source IP address - * @param type The type of transaction + * @param type The type of transaction * @return The persisted Transaction */ public Transaction createTransaction(String sourceIP, TransactionType type) { @@ -113,27 +113,28 @@ public Transaction createTransaction(String sourceIP, TransactionType type) { try { // This can throw an exception under certain auth failures // E.g. if an empty or invalid token is provided - userInfo = SecurityUtil.loadUserInfo(); + userInfo = SecurityUtil.loadUserInfo(); } catch (Exception e) { // Ignore } - transaction.setOrganization(userInfo != null ? userInfo.getOrganization(): null); + transaction.setOrganization(userInfo != null ? userInfo.getOrganization() : null); transaction.setServer(getServer()); - transaction.setSessionId(userInfo != null ? userInfo.getSessionState(): null); + transaction.setSessionId(userInfo != null ? userInfo.getSessionState() : null); transaction.setSourceIp(sourceIP); transaction.setStartTime(new Date()); transaction.setTransactionId(UUID.randomUUID()); transaction.setType(type.getValue()); transaction.setUserId(userInfo != null ? userInfo.getUsername() : null); + transaction.setSpgRole(SecurityUtil.loadSPGBasedOnTask(userInfo, type)); return transactionRepository.save(transaction); } - private String getServer() { + private String getServer() { String hostname = ""; try { hostname = InetAddress.getLocalHost().getHostName(); logger.debug("The hostname is {}", hostname); - } catch (UnknownHostException e) { + } catch (UnknownHostException e) { logger.warn("Could not get server name"); } return hostname; @@ -143,7 +144,7 @@ private String getServer() { * Creates a new {@link TransactionEvent}. * * @param transaction The associated Transaction - * @param eventType The type of event + * @param eventType The type of event * @return The persisted TransactionEvent. */ public TransactionEvent createTransactionEvent(Transaction transaction, TransactionEventType eventType) { @@ -154,11 +155,12 @@ public TransactionEvent createTransactionEvent(Transaction transaction, Transact * Creates a new {@link TransactionEvent}. * * @param transaction The associated Transaction - * @param eventType The type of event - * @param messageId The associated message ID + * @param eventType The type of event + * @param messageId The associated message ID * @return The persisted TransactionEvent. */ - public TransactionEvent createTransactionEvent(Transaction transaction, TransactionEventType eventType, String messageId) { + public TransactionEvent createTransactionEvent(Transaction transaction, TransactionEventType eventType, + String messageId) { TransactionEvent transactionEvent = new TransactionEvent(); transactionEvent.setEventTime(new Date()); transactionEvent.setMessageId(messageId); @@ -166,20 +168,20 @@ public TransactionEvent createTransactionEvent(Transaction transaction, Transact transactionEvent.setType(eventType.getValue()); return transactionEventRepository.save(transactionEvent); } - + /** * Creates a new {@link EventMessage}. * * @param transactionEvent The associated TransactionEvent - * @param level The level of the event (e.g.ERROR) - * @param status The HTTP Status code related to the message + * @param level The level of the event (e.g.ERROR) + * @param status The HTTP Status code related to the message */ public EventMessage createEventMessage(TransactionEvent transactionEvent, ErrorLevel level, HttpStatus status) { - EventMessage eventMessage = new EventMessage(); - eventMessage.setErrorCode(Integer.toString(status.value())); - eventMessage.setErrorLevel(level); - eventMessage.setMessageText(status.getReasonPhrase()); - eventMessage.setTransactionEvent(transactionEvent); + EventMessage eventMessage = new EventMessage(); + eventMessage.setErrorCode(Integer.toString(status.value())); + eventMessage.setErrorLevel(level); + eventMessage.setMessageText(status.getReasonPhrase()); + eventMessage.setTransactionEvent(transactionEvent); return eventMessageRepository.save(eventMessage); } @@ -187,16 +189,17 @@ public EventMessage createEventMessage(TransactionEvent transactionEvent, ErrorL * Creates a new {@link EventMessage}. * * @param transactionEvent The associated TransactionEvent - * @param level The level of the event (e.g.ERROR) - * @param exception The associated exception - * @param status The HTTP Status code related to the message + * @param level The level of the event (e.g.ERROR) + * @param exception The associated exception + * @param status The HTTP Status code related to the message */ - public EventMessage createEventMessage(TransactionEvent transactionEvent, ErrorLevel level, HttpStatus status, Exception exception) { - EventMessage eventMessage = new EventMessage(); - eventMessage.setErrorCode(Integer.toString(status.value())); - eventMessage.setErrorLevel(level); - eventMessage.setMessageText(exception.getMessage()); - eventMessage.setTransactionEvent(transactionEvent); + public EventMessage createEventMessage(TransactionEvent transactionEvent, ErrorLevel level, HttpStatus status, + Exception exception) { + EventMessage eventMessage = new EventMessage(); + eventMessage.setErrorCode(Integer.toString(status.value())); + eventMessage.setErrorLevel(level); + eventMessage.setMessageText(exception.getMessage()); + eventMessage.setTransactionEvent(transactionEvent); return eventMessageRepository.save(eventMessage); } @@ -204,21 +207,23 @@ public EventMessage createEventMessage(TransactionEvent transactionEvent, ErrorL * Creates a new {@link AffectedParty}. * * @param transaction The associated Transaction - * @param phn The phn of the affected party - * @param direction The value to indicate if the party is affected when the transaction is being sent or being received. + * @param phn The phn of the affected party + * @param direction The value to indicate if the party is affected when the + * transaction is being sent or being received. */ public AffectedParty createAffectedParty(Transaction transaction, String phn, AffectedPartyDirection direction) { return createAffectedParty(transaction, IdentifierType.PHN, phn, direction); } - + /** * Creates a new {@link AffectedParty}. * - * @param transaction The associated Transaction + * @param transaction The associated Transaction * @param identifierType The type of identifier - * @param identifier The value of the identifier + * @param identifier The value of the identifier */ - public AffectedParty createAffectedParty(Transaction transaction, IdentifierType identifierType, String identifier, AffectedPartyDirection direction) { + public AffectedParty createAffectedParty(Transaction transaction, IdentifierType identifierType, String identifier, + AffectedPartyDirection direction) { AffectedParty affectedParty = new AffectedParty(); affectedParty.setIdentifier(identifier); affectedParty.setIdentifierType(identifierType.getValue()); @@ -226,9 +231,10 @@ public AffectedParty createAffectedParty(Transaction transaction, IdentifierType affectedParty.setTransaction(transaction); return affectedPartyRepository.save(affectedParty); } - + /** * Retrieves distinct organization for audit report. + * * @return list of organization. */ public List getOrganizations() { @@ -237,7 +243,8 @@ public List getOrganizations() { /** * Retrieves audit records for the given search parameters - * @param types Transaction types + * + * @param types Transaction types * @param organizations * @param userId * @param direction @@ -245,33 +252,36 @@ public List getOrganizations() { * @param endDate * @return */ - public Page getAffectedParties(List types, List organizations, String userId, LocalDate startDate, - LocalDate endDate, int page, int rows, String sortField, String sortDirection) { + public Page getAffectedParties(List types, List organizations, List spgRoles, + String userId, LocalDate startDate, LocalDate endDate, int page, int rows, String sortField, + String sortDirection) { logger.info("Querying page {} with {} rows", page, rows); try { Date formattedStartDate = convertLocalDateToDate(startDate); - Date formattedEndDate = convertLocalDateToDate(endDate); + Date formattedEndDate = convertLocalDateToDate(endDate); String property = sortMap.get(sortField); if (StringUtils.isBlank(property)) { property = DEFAULT_SORT; } - Direction direction = StringUtils.isNotEmpty(sortDirection) ? Direction.valueOf(sortDirection) : Direction.DESC; + Direction direction = StringUtils.isNotEmpty(sortDirection) ? Direction.valueOf(sortDirection) + : Direction.DESC; Sort sort = Sort.by(direction, property); - + Pageable pageable = PageRequest.of(page, rows, sort); - - return affectedPartyPageableRepository.findByTransactionAndDirection(types, organizations, userId, AffectedPartyDirection.INBOUND.getValue(), formattedStartDate, - formattedEndDate, pageable); + + return affectedPartyPageableRepository.findByTransactionAndDirection(types, organizations, spgRoles, + userId, AffectedPartyDirection.INBOUND.getValue(), formattedStartDate, formattedEndDate, pageable); } catch (ParseException e) { logger.error(e.getLocalizedMessage()); return null; - } + } } - + /** * This method loads data into csv format + * * @param auditReport * @return */ @@ -281,17 +291,18 @@ public ByteArrayInputStream load(final List auditReport) { /** * This method writes audit report data into csv + * * @param auditReport * @return */ private ByteArrayInputStream writeDataToCsv(final List auditReports) { logger.info("Writing data to the csv format"); - + try (ByteArrayOutputStream stream = new ByteArrayOutputStream(); CSVPrinter printer = new CSVPrinter(new PrintWriter(stream), FORMAT)) { for (AuditRecord auditRecord : auditReports) { - List auditData = Arrays.asList(String.valueOf(auditRecord.getType()), - auditRecord.getOrganization(), auditRecord.getUserId(), + List auditData = Arrays.asList(String.valueOf(auditRecord.getType()), + auditRecord.getOrganization(), auditRecord.getSpgRole(), auditRecord.getUserId(), convertLocalDateTime(auditRecord.getTransactionStartTime()), auditRecord.getAffectedPartyId(), auditRecord.getAffectedPartyType(), auditRecord.getTransactionId()); @@ -315,19 +326,21 @@ private ByteArrayInputStream writeDataToCsv(final List auditReports * @return */ public List getAffectedPartiesForDownload(List types, List organizations, - String userId, LocalDate startDate, LocalDate endDate, String sortField, String sortDirection) { + List spgRoles, String userId, LocalDate startDate, LocalDate endDate, String sortField, + String sortDirection) { try { Date formattedStartDate = convertLocalDateToDate(startDate); Date formattedEndDate = convertLocalDateToDate(endDate); - + String property = sortMap.get(sortField); if (StringUtils.isBlank(property)) { property = DEFAULT_SORT; } - Direction direction = StringUtils.isNotEmpty(sortDirection) ? Direction.valueOf(sortDirection) : Direction.DESC; + Direction direction = StringUtils.isNotEmpty(sortDirection) ? Direction.valueOf(sortDirection) + : Direction.DESC; Sort sort = Sort.by(direction, property); - - return affectedPartyPageableRepository.findByTransactionAndDirection(types, organizations, + + return affectedPartyPageableRepository.findByTransactionAndDirection(types, organizations, spgRoles, userId, AffectedPartyDirection.INBOUND.getValue(), formattedStartDate, formattedEndDate, sort); } catch (ParseException e) { logger.error(e.getLocalizedMessage()); @@ -345,5 +358,5 @@ private String convertLocalDateTime(LocalDateTime dateTime) { private Date convertLocalDateToDate(LocalDate date) throws ParseException { return new SimpleDateFormat(LOCAL_DATE_FORMAT).parse(date.toString()); } - + } diff --git a/backend/src/test/java/ca/bc/gov/hlth/hnweb/controller/AuditControllerTest.java b/backend/src/test/java/ca/bc/gov/hlth/hnweb/controller/AuditControllerTest.java index e99b1d24..acfedf04 100644 --- a/backend/src/test/java/ca/bc/gov/hlth/hnweb/controller/AuditControllerTest.java +++ b/backend/src/test/java/ca/bc/gov/hlth/hnweb/controller/AuditControllerTest.java @@ -42,7 +42,7 @@ public class AuditControllerTest extends BaseControllerTest { @Autowired private AffectedPartyRepository affectedPartyRepository; - + @Autowired private TransactionRepository transactionRepository; @@ -61,7 +61,8 @@ public void testGetOrganization() throws Exception { } @Test - public void testGetAuditReport_withoutOptionalParam() {; + public void testGetAuditReport_withoutOptionalParam() { + ; createAuditReports(2, TransactionType.CHECK_ELIGIBILITY); AuditReportRequest auditReportRequest = new AuditReportRequest(); auditReportRequest.setStartDate(LocalDate.of(2022, 7, 1)); @@ -80,7 +81,7 @@ public void testGetOrganization() throws Exception { @Test public void testGetAuditReport_withOptionalParam() { createAuditReports(1, TransactionType.CHECK_ELIGIBILITY); - + List types = new ArrayList<>(); types.add(TransactionType.CHECK_ELIGIBILITY.name()); types.add(TransactionType.PHN_INQUIRY.name()); @@ -89,15 +90,19 @@ public void testGetAuditReport_withOptionalParam() { orgs.add("00000010"); orgs.add("00000020"); + List spgRoles = new ArrayList<>(); + spgRoles.add("traininghealthauth"); + AuditReportRequest auditReportRequest = new AuditReportRequest(); auditReportRequest.setUserId("hnweb1"); auditReportRequest.setOrganizations(orgs); + auditReportRequest.setSpgRoles(spgRoles); auditReportRequest.setTransactionTypes(types); auditReportRequest.setStartDate(LocalDate.of(2022, 7, 1)); auditReportRequest.setEndDate(LocalDate.of(2022, 12, 8)); auditReportRequest.setPage(0); auditReportRequest.setRows(10); - + ResponseEntity auditReport = auditReportController.getAuditReport(auditReportRequest, createHttpServletRequest()); @@ -105,33 +110,37 @@ public void testGetAuditReport_withOptionalParam() { assertEquals(1, auditReport.getBody().getRecords().size()); } - + @Test public void testGetAuditReports_firstPage() { createAuditReports(15, TransactionType.CHECK_ELIGIBILITY); - + List types = new ArrayList<>(); types.add(TransactionType.CHECK_ELIGIBILITY.name()); List orgs = new ArrayList<>(); orgs.add("00000010"); + List spgRoles = new ArrayList<>(); + spgRoles.add("traininghealthauth"); + AuditReportRequest auditReportRequest = new AuditReportRequest(); auditReportRequest.setUserId("hnweb1"); auditReportRequest.setOrganizations(orgs); + auditReportRequest.setSpgRoles(spgRoles); auditReportRequest.setTransactionTypes(types); auditReportRequest.setStartDate(LocalDate.of(2022, 7, 1)); auditReportRequest.setEndDate(LocalDate.of(2022, 12, 8)); auditReportRequest.setPage(0); auditReportRequest.setRows(10); - + ResponseEntity auditReport = auditReportController.getAuditReport(auditReportRequest, createHttpServletRequest()); assertEquals(HttpStatus.OK, auditReport.getStatusCode()); assertEquals(10, auditReport.getBody().getRecords().size()); } - + @Test public void testGetAuditReports_secondPage() { createAuditReports(15, TransactionType.CHECK_ELIGIBILITY); @@ -141,22 +150,26 @@ public void testGetAuditReports_secondPage() { List orgs = new ArrayList<>(); orgs.add("00000010"); + List spgRoles = new ArrayList<>(); + spgRoles.add("traininghealthauth"); + AuditReportRequest auditReportRequest = new AuditReportRequest(); auditReportRequest.setUserId("hnweb1"); auditReportRequest.setOrganizations(orgs); + auditReportRequest.setSpgRoles(spgRoles); auditReportRequest.setTransactionTypes(types); auditReportRequest.setStartDate(LocalDate.of(2022, 7, 1)); auditReportRequest.setEndDate(LocalDate.of(2022, 12, 8)); auditReportRequest.setPage(1); auditReportRequest.setRows(10); - + ResponseEntity auditReport = auditReportController.getAuditReport(auditReportRequest, createHttpServletRequest()); assertEquals(HttpStatus.OK, auditReport.getStatusCode()); assertEquals(5, auditReport.getBody().getRecords().size()); } - + @Test public void testGetAuditReports_sortAsc() { createAuditReports(5, TransactionType.CHECK_ELIGIBILITY); @@ -165,26 +178,30 @@ public void testGetAuditReports_sortAsc() { List orgs = new ArrayList<>(); orgs.add("00000010"); + List spgRoles = new ArrayList<>(); + spgRoles.add("traininghealthauth"); + AuditReportRequest auditReportRequest = new AuditReportRequest(); auditReportRequest.setUserId("hnweb1"); auditReportRequest.setOrganizations(orgs); + auditReportRequest.setSpgRoles(spgRoles); auditReportRequest.setStartDate(LocalDate.of(2022, 7, 1)); auditReportRequest.setEndDate(LocalDate.of(2022, 12, 8)); auditReportRequest.setPage(0); auditReportRequest.setRows(10); auditReportRequest.setSortDirection("ASC"); auditReportRequest.setSortField("type"); - + ResponseEntity auditReport = auditReportController.getAuditReport(auditReportRequest, createHttpServletRequest()); assertEquals(HttpStatus.OK, auditReport.getStatusCode()); - + List records = auditReport.getBody().getRecords(); assertEquals(10, records.size()); assertEquals(TransactionType.CHECK_ELIGIBILITY.name(), records.get(0).getType()); } - + @Test public void testGetAuditReports_sortDesc() { createAuditReports(5, TransactionType.CHECK_ELIGIBILITY); @@ -193,118 +210,134 @@ public void testGetAuditReports_sortDesc() { List orgs = new ArrayList<>(); orgs.add("00000010"); + List spgRoles = new ArrayList<>(); + spgRoles.add("traininghealthauth"); + AuditReportRequest auditReportRequest = new AuditReportRequest(); auditReportRequest.setUserId("hnweb1"); auditReportRequest.setOrganizations(orgs); + auditReportRequest.setSpgRoles(spgRoles); auditReportRequest.setStartDate(LocalDate.of(2022, 7, 1)); auditReportRequest.setEndDate(LocalDate.of(2022, 12, 8)); auditReportRequest.setPage(0); auditReportRequest.setRows(10); auditReportRequest.setSortDirection("DESC"); auditReportRequest.setSortField("type"); - + ResponseEntity auditReport = auditReportController.getAuditReport(auditReportRequest, createHttpServletRequest()); assertEquals(HttpStatus.OK, auditReport.getStatusCode()); - + List records = auditReport.getBody().getRecords(); assertEquals(10, records.size()); assertEquals(TransactionType.PHN_INQUIRY.name(), records.get(0).getType()); } - + @Test public void testGetAuditReport_downloadCSV() throws IOException { createAuditReports(20, TransactionType.CHECK_ELIGIBILITY); createAuditReports(20, TransactionType.PHN_INQUIRY); - + List orgs = new ArrayList<>(); orgs.add("00000010"); orgs.add("00000020"); + List spgRoles = new ArrayList<>(); + spgRoles.add("traininghealthauth"); + AuditReportRequest auditReportRequest = new AuditReportRequest(); auditReportRequest.setUserId("hnweb1"); - auditReportRequest.setOrganizations(orgs); + auditReportRequest.setOrganizations(orgs); + auditReportRequest.setSpgRoles(spgRoles); auditReportRequest.setStartDate(LocalDate.of(2022, 7, 1)); auditReportRequest.setEndDate(LocalDate.of(2022, 12, 8)); auditReportRequest.setSortDirection("ASC"); auditReportRequest.setSortField("type"); - - ResponseEntity downloadReport = auditReportController.downloadAuditReport(auditReportRequest, + + ResponseEntity downloadReport = auditReportController.downloadAuditReport(auditReportRequest, createHttpServletRequest()); - - List reportData = new ArrayList(); - InputStream downloadData = downloadReport.getBody().getInputStream(); - read(downloadData, reportData); - - assertEquals(HttpStatus.OK, downloadReport.getStatusCode()); - - //Check csv headers and data - assertEquals("Type", reportData.get(0)); - assertEquals("Organization", reportData.get(1)); - assertEquals("User ID", reportData.get(2)); - assertEquals("Transaction Start Time", reportData.get(3)); - assertEquals("Affected Party ID", reportData.get(4)); - assertEquals("Affected Party ID Type", reportData.get(5)); - assertEquals("Transaction ID\r\n" + - "CHECK_ELIGIBILITY", reportData.get(6)); - assertEquals("00000010", reportData.get(7)); - assertEquals("hnweb1", reportData.get(8)); - assertEquals("2022-08-05T00:00:00", reportData.get(9)); - assertEquals("PHN", reportData.get(10)); - - //Check the last (40th) record - assertEquals("00000010", reportData.get(241)); - assertEquals("hnweb1", reportData.get(242)); - assertEquals("2022-08-05T00:00:00", reportData.get(243)); - assertEquals("PHN", reportData.get(244)); + + List reportData = new ArrayList(); + InputStream downloadData = downloadReport.getBody().getInputStream(); + read(downloadData, reportData); + + assertEquals(HttpStatus.OK, downloadReport.getStatusCode()); + + // Check csv headers and data + assertEquals("Type", reportData.get(0)); + assertEquals("Organization", reportData.get(1)); + assertEquals("SPG", reportData.get(2)); + assertEquals("User ID", reportData.get(3)); + assertEquals("Transaction Start Time", reportData.get(4)); + assertEquals("Affected Party ID", reportData.get(5)); + assertEquals("Affected Party ID Type", reportData.get(6)); + assertEquals("Transaction ID\r\n" + "CHECK_ELIGIBILITY", reportData.get(7)); + assertEquals("00000010", reportData.get(8)); + assertEquals("traininghealthauth", reportData.get(9)); + assertEquals("hnweb1", reportData.get(10)); + assertEquals("2022-08-05T00:00:00", reportData.get(11)); + assertEquals("PHN", reportData.get(12)); + + // Check the last (40th) record + assertEquals("00000010", reportData.get(239)); + assertEquals("traininghealthauth", reportData.get(240)); + assertEquals("hnweb1", reportData.get(241)); + assertEquals("2022-08-05T00:00:00", reportData.get(242)); + assertEquals("PHN", reportData.get(243)); } - + @Test public void testGetAuditReport_downloadCSV_sortDesc() throws IOException { createAuditReports(20, TransactionType.CHECK_ELIGIBILITY); createAuditReports(20, TransactionType.PHN_INQUIRY); - + List orgs = new ArrayList<>(); orgs.add("00000010"); orgs.add("00000020"); + List spgRoles = new ArrayList<>(); + spgRoles.add("traininghealthauth"); + AuditReportRequest auditReportRequest = new AuditReportRequest(); auditReportRequest.setUserId("hnweb1"); - auditReportRequest.setOrganizations(orgs); + auditReportRequest.setOrganizations(orgs); + auditReportRequest.setSpgRoles(spgRoles); auditReportRequest.setStartDate(LocalDate.of(2022, 7, 1)); auditReportRequest.setEndDate(LocalDate.of(2022, 12, 8)); auditReportRequest.setSortDirection("DESC"); auditReportRequest.setSortField("type"); - - ResponseEntity downloadReport = auditReportController.downloadAuditReport(auditReportRequest, + + ResponseEntity downloadReport = auditReportController.downloadAuditReport(auditReportRequest, createHttpServletRequest()); - - List reportData = new ArrayList(); - InputStream downloadData = downloadReport.getBody().getInputStream(); - read(downloadData, reportData); - - assertEquals(HttpStatus.OK, downloadReport.getStatusCode()); - - //Check csv headers and data - assertEquals("Type", reportData.get(0)); - assertEquals("Organization", reportData.get(1)); - assertEquals("User ID", reportData.get(2)); - assertEquals("Transaction Start Time", reportData.get(3)); - assertEquals("Affected Party ID", reportData.get(4)); - assertEquals("Affected Party ID Type", reportData.get(5)); - assertEquals("Transaction ID\r\n" + - "PHN_INQUIRY", reportData.get(6)); - assertEquals("00000010", reportData.get(7)); - assertEquals("hnweb1", reportData.get(8)); - assertEquals("2022-08-05T00:00:00", reportData.get(9)); - assertEquals("PHN", reportData.get(10)); - - //Check the last (40th) record - assertEquals("00000010", reportData.get(241)); - assertEquals("hnweb1", reportData.get(242)); - assertEquals("2022-08-05T00:00:00", reportData.get(243)); - assertEquals("PHN", reportData.get(244)); + + List reportData = new ArrayList(); + InputStream downloadData = downloadReport.getBody().getInputStream(); + read(downloadData, reportData); + + assertEquals(HttpStatus.OK, downloadReport.getStatusCode()); + + // Check csv headers and data + assertEquals("Type", reportData.get(0)); + assertEquals("Organization", reportData.get(1)); + assertEquals("SPG", reportData.get(2)); + assertEquals("User ID", reportData.get(3)); + assertEquals("Transaction Start Time", reportData.get(4)); + assertEquals("Affected Party ID", reportData.get(5)); + assertEquals("Affected Party ID Type", reportData.get(6)); + assertEquals("Transaction ID\r\n" + "PHN_INQUIRY", reportData.get(7)); + assertEquals("00000010", reportData.get(8)); + assertEquals("traininghealthauth", reportData.get(9)); + assertEquals("hnweb1", reportData.get(10)); + assertEquals("2022-08-05T00:00:00", reportData.get(11)); + assertEquals("PHN", reportData.get(12)); + + // Check the last (40th) record + assertEquals("00000010", reportData.get(239)); + assertEquals("traininghealthauth", reportData.get(240)); + assertEquals("hnweb1", reportData.get(241)); + assertEquals("2022-08-05T00:00:00", reportData.get(242)); + assertEquals("PHN", reportData.get(243)); } private void read(InputStream input, List reportData) throws IOException { @@ -330,12 +363,13 @@ private void createOrganization() { organizationRepository.save(org); } - + private void createAuditReports(int count, TransactionType transactionType) { for (int i = 0; i < count; i++) { Transaction transaction = new Transaction(); transaction.setOrganization("00000010"); + transaction.setSpgRole("traininghealthauth"); transaction.setServer("server1"); transaction.setSessionId("123456"); transaction.setSourceIp("0:0:0:0:0:0:0:1"); @@ -351,7 +385,7 @@ private void createAuditReports(int count, TransactionType transactionType) { affectedParty.setIdentifierType(IdentifierType.PHN.getValue()); affectedParty.setDirection(AffectedPartyDirection.INBOUND.getValue()); affectedParty.setTransaction(transaction); - + affectedPartyRepository.save(affectedParty); } } diff --git a/frontend/src/views/reports/AuditReporting.vue b/frontend/src/views/reports/AuditReporting.vue index b8dc6b79..f6f0c10e 100644 --- a/frontend/src/views/reports/AuditReporting.vue +++ b/frontend/src/views/reports/AuditReporting.vue @@ -30,6 +30,18 @@ + + + SPG +
+ +
+
+
@@ -73,6 +85,7 @@ > + @@ -115,6 +128,7 @@ export default { startDate: dayjs().subtract(1, 'month').startOf('month').toDate(), endDate: dayjs().subtract(1, 'month').endOf('month').toDate(), organizationOptions: [], + spgRoles: [], transactionTypes: [], searchOk: false, searching: false, @@ -155,6 +169,7 @@ export default { 'UpdateContractAddress', 'UpdateNumberAndDept', ], + spgOptions: ['DUMMY', 'E45', 'ELIGIBILITY', 'VISARESIDENT', 'TRAININGHEALTHAUTH', 'PBFUSER', 'AUDITUSER', 'MANAGEMSPPAYEENUMBER'], } }, mounted() { @@ -197,6 +212,7 @@ export default { this.auditReportRequest.transactionTypes = this.transactionTypes this.auditReportRequest.startDate = this.startDate this.auditReportRequest.endDate = this.endDate + this.auditReportRequest.spgRoles = this.spgRoles }, async loadLazyData() { this.loading = true @@ -204,6 +220,7 @@ export default { this.result = ( await AuditService.getAuditReport({ organizations: this.organizations, + spgRoles: this.spgRoles, transactionTypes: this.transactionTypes, userId: this.userId, startDate: this.startDate, @@ -252,6 +269,7 @@ export default { try { await AuditService.downloadAuditReport({ organizations: this.auditReportRequest.organizations, + spgRoles: this.auditReportRequest.spgRoles, transactionTypes: this.auditReportRequest.transactionTypes, userId: this.auditReportRequest.userId, startDate: this.auditReportRequest.startDate, @@ -284,6 +302,7 @@ export default { resetForm() { this.userId = '' this.organizations = [] + this.spgRoles = [] this.transactionTypes = [] this.startDate = dayjs().subtract(1, 'month').startOf('month').toDate() this.endDate = dayjs().subtract(1, 'month').endOf('month').toDate() diff --git a/frontend/tests/e2e/pages/reports/AuditReportingPage.js b/frontend/tests/e2e/pages/reports/AuditReportingPage.js index 8c1f6001..16d235d9 100644 --- a/frontend/tests/e2e/pages/reports/AuditReportingPage.js +++ b/frontend/tests/e2e/pages/reports/AuditReportingPage.js @@ -7,6 +7,7 @@ class AuditReportingPage { this.checkBoxInput1 = Selector('[for="00000010"]') this.checkBoxInput2 = Selector('[for="CheckEligibility"]') this.checkBoxInput3 = Selector('[for="PHNInquiry"]') + this.checkBoxInput4 = Selector('[for="TRAININGHEALTHAUTH"]') this.startDateInput = Selector('#dp-input-startDate') this.endDateInput = Selector('#dp-input-endDate') this.submitButton = Selector('button[type="submit"]') diff --git a/frontend/tests/e2e/tests/reports/AuditReportingTest.js b/frontend/tests/e2e/tests/reports/AuditReportingTest.js index dbf420d5..f2b4cadb 100644 --- a/frontend/tests/e2e/tests/reports/AuditReportingTest.js +++ b/frontend/tests/e2e/tests/reports/AuditReportingTest.js @@ -1,9 +1,8 @@ -import dayjs from 'dayjs' - -import { OUTPUT_DATE_FORMAT } from '../../../../src/util/constants' -import { SITE_UNDER_TEST } from '../../configuration' import AlertPage from '../../pages/AlertPage' import AuditReportingPage from '../../pages/reports/AuditReportingPage' +import { OUTPUT_DATE_FORMAT } from '../../../../src/util/constants' +import { SITE_UNDER_TEST } from '../../configuration' +import dayjs from 'dayjs' import { regularAccUser } from '../../roles/roles' const ERROR_MESSAGE = 'Please correct errors before submitting' @@ -81,6 +80,7 @@ test('Check Error message when end date is before start date', async (t) => { .click(AuditReportingPage.checkBoxInput1) //Check box .click(AuditReportingPage.checkBoxInput2) //Check box .click(AuditReportingPage.checkBoxInput3) //Check box + .click(AuditReportingPage.checkBoxInput4) //Check box .selectText(AuditReportingPage.startDateInput) .pressKey('delete') .typeText(AuditReportingPage.startDateInput, '20220701') @@ -103,13 +103,14 @@ test('Check properly filled form passes validation and validate results', async .click(AuditReportingPage.checkBoxInput1) //Check box .click(AuditReportingPage.checkBoxInput2) //Check box .click(AuditReportingPage.checkBoxInput3) //Check box + .click(AuditReportingPage.checkBoxInput4) //Check box .selectText(AuditReportingPage.startDateInput) .pressKey('delete') - .typeText(AuditReportingPage.startDateInput, '20220701') + .typeText(AuditReportingPage.startDateInput, '20221207') .pressKey('tab') .selectText(AuditReportingPage.endDateInput) .pressKey('delete') - .typeText(AuditReportingPage.endDateInput, '20220708') + .typeText(AuditReportingPage.endDateInput, '20221212') .pressKey('tab') // When I click the submit button .click(AuditReportingPage.submitButton) @@ -123,7 +124,7 @@ test('Check properly filled form passes validation and validate results', async .expect(AuditReportingPage.resultsTable.child('thead').exists) .ok() .expect(AuditReportingPage.resultsTable.child('tbody').child('tr').count) - .eql(2) + .eql(1) .expect(AuditReportingPage.resultsRow1.exists) .ok() .expect(AuditReportingPage.resultsRow1.child('td').exists) @@ -131,19 +132,21 @@ test('Check properly filled form passes validation and validate results', async // Validate the first row .expect(AuditReportingPage.resultsRow1.child('td').nth(0).textContent) - .eql('CheckEligibility') + .eql('PHNInquiry') .expect(AuditReportingPage.resultsRow1.child('td').nth(1).textContent) .eql('00000010') .expect(AuditReportingPage.resultsRow1.child('td').nth(2).textContent) - .eql('hnweb1') + .eql('TRAININGHEALTHAUTH') .expect(AuditReportingPage.resultsRow1.child('td').nth(3).textContent) - .eql('2022-07-06T22:23:27.699') + .eql('hnweb1') .expect(AuditReportingPage.resultsRow1.child('td').nth(4).textContent) - .eql('9331926919') + .eql('2022-12-12T13:53:12.059') .expect(AuditReportingPage.resultsRow1.child('td').nth(5).textContent) - .eql('PHN') + .eql('9873102617') .expect(AuditReportingPage.resultsRow1.child('td').nth(6).textContent) - .eql('5fa5835f-b5bb-4321-9804-aa84edc64077') + .eql('PHN') + .expect(AuditReportingPage.resultsRow1.child('td').nth(7).textContent) + .eql('d9291fb5-6a30-43ea-bd71-891c02b939d0') }) test('Check properly filled form passes validation when no record found', async (t) => { @@ -153,6 +156,7 @@ test('Check properly filled form passes validation when no record found', async .click(AuditReportingPage.checkBoxInput1) //Check box .click(AuditReportingPage.checkBoxInput2) //Check box .click(AuditReportingPage.checkBoxInput3) //Check box + .click(AuditReportingPage.checkBoxInput4) //Check box .selectText(AuditReportingPage.startDateInput) .pressKey('delete') .typeText(AuditReportingPage.startDateInput, '20220701') @@ -175,8 +179,13 @@ test('Check clear button clears the form', async (t) => { .click(AuditReportingPage.checkBoxInput1) //Check box .click(AuditReportingPage.checkBoxInput2) //Check box .click(AuditReportingPage.checkBoxInput3) //Check box + .click(AuditReportingPage.checkBoxInput4) //Check box + .selectText(AuditReportingPage.startDateInput) + .pressKey('delete') .typeText(AuditReportingPage.startDateInput, '20220701') .pressKey('tab') + .selectText(AuditReportingPage.endDateInput) + .pressKey('delete') .typeText(AuditReportingPage.endDateInput, '20220708') .pressKey('tab') // When I click the Clear button @@ -190,4 +199,6 @@ test('Check clear button clears the form', async (t) => { .notOk() .expect(AuditReportingPage.checkBoxInput3.checked) .notOk() + .expect(AuditReportingPage.checkBoxInput4.checked) + .notOk() }) From 863fca5fb8a3ae8da247c4c205eaa5f7d5f59ec9 Mon Sep 17 00:00:00 2001 From: weskubo-cgi Date: Wed, 14 Dec 2022 13:39:55 -0800 Subject: [PATCH 2/5] Added missing sort mapping for spgRole. Minor style tweaks to add spacing for multi checkboxes. --- .../gov/hlth/hnweb/service/AuditService.java | 1 + frontend/src/views/reports/AuditReporting.vue | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/backend/src/main/java/ca/bc/gov/hlth/hnweb/service/AuditService.java b/backend/src/main/java/ca/bc/gov/hlth/hnweb/service/AuditService.java index 931700b6..6a4be0ce 100644 --- a/backend/src/main/java/ca/bc/gov/hlth/hnweb/service/AuditService.java +++ b/backend/src/main/java/ca/bc/gov/hlth/hnweb/service/AuditService.java @@ -95,6 +95,7 @@ public class AuditService { sortMap.put("affectedPartyId", "identifier"); sortMap.put("affectedPartyType", "identifierType"); sortMap.put("organization", "transaction.organization"); + sortMap.put("spgRole", "transaction.spgRole"); sortMap.put("transactionStartTime", "transaction.startTime"); sortMap.put("type", "transaction.type"); sortMap.put("userId", "transaction.userId"); diff --git a/frontend/src/views/reports/AuditReporting.vue b/frontend/src/views/reports/AuditReporting.vue index f6f0c10e..ddef7287 100644 --- a/frontend/src/views/reports/AuditReporting.vue +++ b/frontend/src/views/reports/AuditReporting.vue @@ -7,8 +7,8 @@ - - Organization + + Organization