Skip to content

Commit

Permalink
Merge branch 'main' into bug/CSTM-CPC-1014-Fix-pet-date-and-update-pe…
Browse files Browse the repository at this point in the history
…t-form
  • Loading branch information
1-emil authored Oct 23, 2023
2 parents 2d50478 + dbc92c9 commit a7bd459
Show file tree
Hide file tree
Showing 45 changed files with 703 additions and 157 deletions.
50 changes: 21 additions & 29 deletions api-gateway/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,39 +21,31 @@ repositories {


dependencies {


implementation 'io.jsonwebtoken:jjwt-api:0.11.2'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.2'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.2'

implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.yaml:snakeyaml:2.2'

implementation 'org.webjars:bootstrap:5.1.0' // https://mvnrepository.com/artifact/org.webjars/bootstrap
implementation 'org.webjars:jquery:3.6.0' // https://mvnrepository.com/artifact/org.webjars/jquery
implementation 'org.webjars:angularjs:2.0.0-alpha.22' // https://mvnrepository.com/artifact/org.webjars/angularjs

implementation 'org.webjars.bower:angular-ui-router:1.0.28' // https://mvnrepository.com/artifact/org.webjars.bower/angular-ui-router
implementation 'org.webjars:webjars-locator-core:0.47' // https://mvnrepository.com/artifact/org.webjars/webjars-locator-core
implementation 'ro.isdc.wro4j:wro4j-core:1.10.1' // https://mvnrepository.com/artifact/ro.isdc.wro4j/wro4j-core
implementation 'com.github.houbie:lesscss-gradle-plugin:1.0.3-less-1.7.0' // https://mvnrepository.com/artifact/com.github.houbie/lesscss-gradle-plugin
implementation 'com.github.houbie:lesscss-gradle-plugin:1.0.3-less-1.7.0' // https://mvnrepository.com/artifact/com.github.houbie/lesscss-gradle-plugin
implementation 'org.jolokia:jolokia-core:1.7.0' // https://mvnrepository.com/artifact/org.jolokia/jolokia-core
implementation 'io.springfox:springfox-boot-starter:3.0.0'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310' //for serializing and deserializing java.time.LocalDateTime

runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.2', 'io.jsonwebtoken:jjwt-jackson:0.11.2'

implementation 'org.webjars:bootstrap:5.1.0', // https://mvnrepository.com/artifact/org.webjars/bootstrap
'org.springframework.boot:spring-boot-starter-webflux',
'org.springframework.boot:spring-boot-starter-actuator',
'org.springframework.boot:spring-boot-starter-validation',
'io.jsonwebtoken:jjwt-api:0.11.2',
'org.webjars:jquery:3.7.1', // https://mvnrepository.com/artifact/org.webjars/jquery
'org.webjars:angularjs:2.0.0-alpha.22', // https://mvnrepository.com/artifact/org.webjars/angularjs
'org.webjars.bower:angular-ui-router:1.0.28', // https://mvnrepository.com/artifact/org.webjars.bower/angular-ui-router
'org.webjars:webjars-locator-core:0.47', // https://mvnrepository.com/artifact/org.webjars/webjars-locator-core
'ro.isdc.wro4j:wro4j-core:1.10.1', // https://mvnrepository.com/artifact/ro.isdc.wro4j/wro4j-core
'com.github.houbie:lesscss-gradle-plugin:1.0.3-less-1.7.0', // https://mvnrepository.com/artifact/com.github.houbie/lesscss-gradle-plugin
'org.jolokia:jolokia-core:1.7.0', // https://mvnrepository.com/artifact/org.jolokia/jolokia-core
'io.springfox:springfox-boot-starter:3.0.0',
'com.fasterxml.jackson.datatype:jackson-datatype-jsr310', //for serializing and deserializing java.time.LocalDateTime
'org.yaml:snakeyaml:2.2'

testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation 'io.projectreactor:reactor-test'
testImplementation 'com.squareup.okhttp3:okhttp:4.11.0'
testImplementation 'com.squareup.okhttp3:mockwebserver:4.11.0'


testImplementation 'com.squareup.okhttp3:okhttp:4.11.0',
'com.squareup.okhttp3:mockwebserver:4.11.0',
'io.projectreactor:reactor-test'
}

jacoco {
Expand Down Expand Up @@ -89,4 +81,4 @@ test {
testLogging {
events "passed", "skipped", "failed"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.petclinic.bffapigateway.dtos.Visits.*;
import com.petclinic.bffapigateway.dtos.Visits.Status;
import com.petclinic.bffapigateway.dtos.Visits.VisitRequestDTO;
import com.petclinic.bffapigateway.dtos.Visits.VisitResponseDTO;
import com.petclinic.bffapigateway.exceptions.BadRequestException;
import com.petclinic.bffapigateway.exceptions.DuplicateTimeException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
Expand All @@ -24,10 +25,8 @@
*/

@Component
@Slf4j
public class VisitsServiceClient {
private final WebClient webClient;

@Autowired
public VisitsServiceClient(
@Value("${app.visits-service-new.host}") String visitsServiceHost,
Expand Down Expand Up @@ -125,7 +124,6 @@ else if (httpStatus == HttpStatus.CONFLICT){
else {
return Mono.error(new BadRequestException(message));
}

} catch (IOException e) {
// Handle parsing error
return Mono.error(new BadRequestException("Bad Request"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ public class VisitRequestDTO {
private LocalDateTime visitDate;
private String description;
private String petId;
private String ownerId;
private String jwtToken;//used to get the userDetails from the Auth-Service when sending visit emails
private String practitionerId;
private Status status;

public VisitRequestDTO(LocalDateTime now, String description, String petId, String practitionerId) {
public VisitRequestDTO(LocalDateTime now, String description, String petId, String ownerId, String jwtToken, String practitionerId) {
this.visitDate = now;
this.description = description;
this.petId = petId;
this.ownerId = ownerId;
this.jwtToken = jwtToken;
this.practitionerId = practitionerId;
this.status = Status.UPCOMING;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import reactor.core.publisher.Mono;

import java.util.Map;
import java.util.List;
import java.util.Optional;

/**
Expand Down Expand Up @@ -262,8 +261,9 @@ public Mono<VisitResponseDTO> getVisitByVisitId(@PathVariable String visitId){
return visitsServiceClient.getVisitByVisitId(visitId);
}
@PostMapping(value = "visit/owners/{ownerId}/pets/{petId}/visits", consumes = "application/json", produces = "application/json")
Mono<ResponseEntity<VisitResponseDTO>> addVisit(@RequestBody VisitRequestDTO visit, @PathVariable String ownerId, @PathVariable String petId) {
// visit.setPetId(petId);
Mono<ResponseEntity<VisitResponseDTO>> addVisit(@RequestBody VisitRequestDTO visit, @PathVariable String ownerId, /*@PathVariable String petId,*/ @CookieValue("Bearer") String auth) {
visit.setOwnerId(ownerId);
visit.setJwtToken(auth);
return visitsServiceClient.createVisitForPet(visit).map(ResponseEntity.status(HttpStatus.CREATED)::body)
.defaultIfEmpty(ResponseEntity.badRequest().build());
}
Expand Down
6 changes: 6 additions & 0 deletions api-gateway/src/main/resources/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,12 @@
<script src="scripts/pet-type-list/pet-type-list.controller.js"></script>
<script src="scripts/pet-type-list/pet-type-list.component.js"></script>

<script src="scripts/auth/update-role-form/role-update.config.js"></script>
<script src="scripts/auth/update-role-form/role-update.service.js"></script>
<script src="scripts/auth/update-role-form/role-update.controller.js"></script>
<script src="scripts/auth/update-role-form/role-update.component.js"></script>



<script src="scripts/pet-details/pet-details.js"></script>
<script src="scripts/pet-details/pet-details.controller.js"></script>
Expand Down
2 changes: 1 addition & 1 deletion api-gateway/src/main/resources/static/scripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const petClinicApp = angular.module('petClinicApp', [
'ui.router', 'layoutNav', 'layoutFooter', 'layoutWelcome', 'ownerList', 'ownerDetails', 'ownerForm', 'ownerRegister', 'petRegister', 'petForm'
, 'visits', 'visit', 'visitList' , 'vetList','vetForm','vetDetails', 'billForm', 'billUpdateForm', 'loginForm', 'rolesDetails', 'signupForm', 'productDetailsInfo',
'billDetails', 'billsByOwnerId', 'billHistory','billsByVetId','inventoryList', 'inventoryForm', 'productForm','inventoryProductList', 'inventoryUpdateForm', 'productUpdateForm',
'verification' , 'adminPanel','resetPwdForm','forgotPwdForm','petTypeList', 'petDetails','userDetails','managerForm']);
'verification' , 'adminPanel','resetPwdForm','forgotPwdForm','petTypeList', 'petDetails','userDetails','managerForm','userModule']);



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ <h2 class="admin-panel">Users</h2>
<tr>
<th>Username</th>
<th>Email</th>
<th>Role</th>
<th>Options</th>
</tr>
</thead>
Expand All @@ -23,8 +24,15 @@ <h2 class="admin-panel">Users</h2>
</a>
</td>
<td>{{user.email}}</td>
<td>
<!-- Using a nested ng-repeat to loop over each role in the user.roles array -->
<span ng-repeat="role in user.roles">
{{ role.name }}<span ng-if="!$last">, </span>
</span>
</td>
<td>
<input class="add-vet-button btn btn-success" type="button" value="Delete" ng-click="removeUser(user.userId)"/>
<button class="btn btn-warning" ui-sref="updateUserRole({ userId: user.userId })">Update Role</button>
</td>
</tr>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict';

angular.module('userModule')
.component('updateUserRoleComponent', {
templateUrl: 'scripts/auth/update-role-form/role-update.template.html',
controller: 'UpdateUserRoleController',
bindings: {
userId: '<'
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';

angular.module('userModule', ['ui.router'])
.config(['$stateProvider', function($stateProvider) {
$stateProvider
.state('updateUserRole', {
parent: 'app',
url: '/users/:userId/updateRole',
component: 'updateUserRoleComponent',
resolve: {
userId: ['$stateParams', function($stateParams) {
return $stateParams.userId;
}]
}
});
}]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
'use strict';

angular.module('userModule')
.controller('UpdateUserRoleController', ['$scope', '$http', 'UserService', '$state', function($scope, $http, UserService, $state) {
var ctrl = this; // Capture the controller instance

$scope.roles = UserService.getAvailableRoles();
$scope.selectedRole = {};

// Use $onInit lifecycle hook to set $scope.userId
ctrl.$onInit = function() {
$scope.userId = ctrl.userId;
};

$scope.selectedRoles = {};

$scope.updateRole = function() {
var rolesList = [];
for (var role in $scope.selectedRoles) {
if ($scope.selectedRoles[role]) {
rolesList.push(role);
}
}

if (rolesList.length === 0) {
alert('Please select at least one role.');
return;
}

if (rolesList.length > 1) {
alert('Please select only one role.');
return;
}

var rolesChangeRequest = {
roles: rolesList
};

// Send the PATCH request
$http({
method: 'PATCH',
url: 'api/gateway/users/' + $scope.userId,
data: rolesChangeRequest,
headers: {
'Content-Type': 'application/json',
// Add token headers if needed
}
})
.then(function successCallback(response) {
alert('Roles updated successfully!');
$state.go('AdminPanel');
}, function errorCallback(response) {
alert('Failed to update roles. ' + response.data.message);
});
};
}]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';

angular.module('userModule').service('UserService', [function() {
this.getAvailableRoles = function() {
return ['ADMIN', 'VET', 'OWNER'];
};

}]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<h2>Update User Role</h2>
<form style="background-color: #f5f5f5; padding: 20px; border-radius: 10px; box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);">
<div class="form-group">
<label>Select Role:</label>
<div ng-repeat="role in roles" class="form-check">
<input type="checkbox" class="form-check-input" id="{{role}}" ng-model="selectedRoles[role]" ng-true-value="'{{role}}'" ng-false-value="undefined">
<label class="form-check-label" for="{{role}}">{{role}}</label>
</div>
</div>
<button type="button" class="btn btn-warning" ng-click="updateRole()">Update Roles</button>
<a ui-sref="AdminPanel" class="btn btn-secondary">Cancel</a>
</form>
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ void createVisitForPet_Valid() throws JsonProcessingException {
LocalDateTime.parse("2024-11-25 13:45", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")),
"Test Visit",
"1",
"f470653d-05c5-4c45-b7a0-7d70f003d2ac",
"testJwtToken",
"2"
);

Expand Down Expand Up @@ -178,6 +180,8 @@ void createVisitForPet_Valid() throws JsonProcessingException {

// Assert
StepVerifier.create(resultMono)
.expectNext()
.expectNext()
.expectNextMatches(visitResponse -> Objects.equals(visitResponse.getVisitId(), visitResponseDTO.getVisitId()))
.verifyComplete();

Expand All @@ -191,6 +195,8 @@ void createVisitForPet_DuplicateTime_ThrowsDuplicateTimeException() throws JsonP
LocalDateTime.parse("2024-11-25 13:45", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")),
"Test Visit",
"1",
"f470653d-05c5-4c45-b7a0-7d70f003d2ac",
"testJwtToken",
"2"
);

Expand Down Expand Up @@ -218,6 +224,8 @@ void createVisitForPet_NotFound_ThrowsNotFoundException() throws JsonProcessingE
LocalDateTime.parse("2024-11-25 13:45", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")),
"Test Visit",
"1",
"f470653d-05c5-4c45-b7a0-7d70f003d2ac",
"testJwtToken",
"2"
);

Expand Down Expand Up @@ -245,6 +253,8 @@ void createVisitForPet_BadRequest_ThrowsBadRequestException() throws JsonProcess
LocalDateTime.parse("2024-11-25 13:45", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")),
"Test Visit",
"1",
"f470653d-05c5-4c45-b7a0-7d70f003d2ac",
"testJwtToken",
"2"
);

Expand Down Expand Up @@ -272,6 +282,8 @@ void createVisitForPet_InvalidErrorResponse_ThrowsBadRequestException() throws J
LocalDateTime.parse("2024-11-25 13:45", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")),
"Test Visit",
"1",
"f470653d-05c5-4c45-b7a0-7d70f003d2ac",
"testJwtToken",
"2"
);

Expand Down Expand Up @@ -322,7 +334,7 @@ void getVisitById() throws Exception {
.visitDate(LocalDateTime.parse("2024-11-25 13:45", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")))
.description("this is a dummy description")
.petId("2")
.petName("YourPetNameHere")
.petName("YourPetNameHere")
.petBirthDate(new Date())
.practitionerId("2")
.vetFirstName("VetFirstNameHere")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,5 @@ public interface UserService {
void updatePassword(String newPassword, String token);

void processResetPassword(UserResetPwdWithTokenRequestModel resetRequest);
UserPasswordLessDTO updateUserRole(String id, RolesChangeRequestDTO roles, String token);
UserPasswordLessDTO updateUserRole(String userId, RolesChangeRequestDTO roles, String token);
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
public interface UserRepo extends JpaRepository<User, Long> {

Optional<User> findByEmail(String email);
User findUserById(long id);

Optional<User> findByUsername(String username);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
import lombok.NoArgsConstructor;

import java.util.List;

Check warning on line 8 in auth-service/src/main/java/com/petclinic/authservice/presentationlayer/User/RolesChangeRequestDTO.java

View workflow job for this annotation

GitHub Actions / Qodana for JVM

Unused import

Unused import `import java.util.List;`
import java.util.Set;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder(toBuilder = true)
public class RolesChangeRequestDTO {
List<String> roles;
Set<String> roles;
}
Loading

0 comments on commit a7bd459

Please sign in to comment.