Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.testify.Testify_Backend.service.ExamManagementService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

Expand Down Expand Up @@ -194,4 +195,87 @@ public ResponseEntity<List<CandidateConflictExamResponse>> getCandidateConflicti
return ResponseEntity.ok(response);
}

@PutMapping("/{examId}/real-time-monitoring")
public ResponseEntity<GenericResponse> updateRealTimeMonitoring(
@PathVariable Long examId,
@RequestBody RealTimeMonitoringRequest dto) {
try {
// Delegate to the service and return the response directly
GenericResponse response = examManagementService.updateRealTimeMonitoring(examId, dto);
return ResponseEntity.ok(response);
} catch (Exception ex) {
return ResponseEntity.status(500).body(new GenericResponse("false", "Error: " + ex.getMessage()));
}
}

@GetMapping("/{examId}/real-time-monitoring")
public ResponseEntity<RealTimeMonitoringResponse> getRealTimeMonitoringStatus(@PathVariable Long examId) {
try {
RealTimeMonitoringResponse response = examManagementService.getRealTimeMonitoringStatus(examId);
return ResponseEntity.ok(response);
} catch (Exception ex) {
return ResponseEntity.status(500).body(null);
}
}

@PutMapping("/{examId}/browser-lockdown")
public ResponseEntity<GenericResponse> updateBrowserLockdown(
@PathVariable Long examId,
@RequestParam boolean browserLockdown) {
try {
GenericResponse response = examManagementService.updateBrowserLockdown(examId, browserLockdown);
return ResponseEntity.ok(response);
} catch (Exception ex) {
return ResponseEntity.status(500).body(new GenericResponse("false", "Error: " + ex.getMessage()));
}
}

@GetMapping("/{examId}/browser-lockdown")
public ResponseEntity<BrowserLockdownResponse> getBrowserLockdown(@PathVariable Long examId) {
try {
boolean browserLockdown = examManagementService.getBrowserLockdownStatus(examId);
return ResponseEntity.ok(new BrowserLockdownResponse(browserLockdown));
} catch (Exception ex) {
return ResponseEntity.status(500).body(null); // Handle errors gracefully
}
}

@PutMapping("/{examId}/hosted")
public ResponseEntity<GenericResponse> updateHosted(@PathVariable Long examId, @RequestParam boolean hosted) {
try {
GenericResponse response = examManagementService.updateHostedStatus(examId, hosted);
return ResponseEntity.ok(response);
} catch (Exception ex) {
return ResponseEntity.status(500).body(new GenericResponse("false", "Error: " + ex.getMessage()));
}
}

@GetMapping("/{examId}/hosted")
public ResponseEntity<HostedResponse> getHosted(@PathVariable Long examId) {
try {
boolean hosted = examManagementService.getHostedStatus(examId);
log.info(String.valueOf(hosted));
return ResponseEntity.ok(new HostedResponse(hosted));
} catch (Exception ex) {
return ResponseEntity.status(500).body(null);
}
}

@PostMapping("/{examId}/set-moderator")
public ResponseEntity<String> setModerator(@PathVariable Long examId, @RequestBody ModeratorRequest moderatorRequest) {
log.info("Setting moderator for examId: " + examId);
try {
examManagementService.assignModerator(examId, moderatorRequest.getModeratorEmail());
return ResponseEntity.ok("Moderator assigned successfully.");
} catch (RuntimeException ex) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ex.getMessage());
}
}

@GetMapping("/{examId}/moderator")
public ResponseEntity<ModeratorResponse> getModerator(@PathVariable Long examId) {
ModeratorResponse moderatorResponse = examManagementService.getModeratorDetails(examId);
return ResponseEntity.ok(moderatorResponse); // Returns null in the body if no moderator exists
}

}
12 changes: 12 additions & 0 deletions src/main/java/com/testify/Testify_Backend/model/Exam.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,16 @@ public class Exam {
@OneToMany(mappedBy = "exam", cascade = CascadeType.ALL)
private List<Grade> gradings;

@Column(nullable = false)
private boolean realTimeMonitoring = false;

@Column
private String zoomLink;

@Column(nullable = false)
private boolean browserLockdown = false;

@Column(nullable = false)
private boolean hosted = false;

}
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,6 @@ public class ExamSetter extends User{

@OneToMany(mappedBy = "moderator")
private Set<Exam> moderatedExams;


}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,5 @@ public interface CandidateRepository extends JpaRepository<Candidate, Long> {
List<Candidate> findCandidatesAssignedToExamWithConflictingExams(Long examId, LocalDateTime startDatetime, LocalDateTime endDatetime);

boolean existsByEmail(String currentUserEmail);
Set<Candidate> findAllByEmailIn(List<String> emails);
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.testify.Testify_Backend.requests.exam_management;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class ModeratorRequest {
private String moderatorEmail;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.testify.Testify_Backend.requests.exam_management;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class RealTimeMonitoringRequest {
private boolean realTimeMonitoring;
private String zoomLink;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
@AllArgsConstructor
@Data
public class GenericResponse {
private String code;
private String success;
private String message;
private Object content;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.testify.Testify_Backend.responses.exam_management;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class BrowserLockdownResponse {
private boolean browserLockdown;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.testify.Testify_Backend.responses.exam_management;

import com.testify.Testify_Backend.enums.OrderType;
import jakarta.persistence.Column;
import lombok.*;

import java.time.LocalDateTime;
Expand Down Expand Up @@ -31,4 +32,8 @@ public class ExamResponse {
private OrderType orderType;
private FixedOrderResponse fixedOrder;
private RandomOrderResponse randomOrder;
private boolean realTimeMonitoring;
private String zoomLink;
private boolean browserLockdown;
private boolean hosted;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.testify.Testify_Backend.responses.exam_management;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class HostedResponse {
private boolean hosted;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.testify.Testify_Backend.responses.exam_management;

import lombok.*;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class ModeratorResponse {
private String email;
private String firstName;
private String lastName;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.testify.Testify_Backend.responses.exam_management;

import lombok.*;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class RealTimeMonitoringResponse {
private boolean realTimeMonitoring;
private String zoomLink;
}
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,10 @@ public RegisterResponse register(@ModelAttribute RegistrationRequest request, bo
// Log the confirmation link
log.info("Confirmation link: {}", link);

// emailSender.send(
// request.getEmail(),
// buildEmail(request.getEmail(), link)
// );
emailSender.send(
request.getEmail(),
buildEmail(request.getEmail(), link)
);

//TODO: save jwt token
var jwtToken = jwtService.generateToken(savedUser);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import java.util.List;

public interface CandidateService {
List<CandidateExam> getCandidateExams();

List<CandidateResponse> getAllCandidatesForSearch();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,24 @@ public class EmailSenderImpl implements EmailSender {
private final static Logger LOGGER = LoggerFactory
.getLogger(EmailSenderImpl.class);

// private final JavaMailSender mailSender;
private final JavaMailSender mailSender;

@Override
@Async
public void send(String to, String email) {
// try {
// MimeMessage mimeMessage = mailSender.createMimeMessage();
// MimeMessageHelper helper =
// new MimeMessageHelper(mimeMessage, "utf-8");
// helper.setText(email, true);
// helper.setTo(to);
// helper.setSubject("Confirm your email");
// helper.setFrom("hello@amigoscode.com");
// mailSender.send(mimeMessage);
// } catch (MessagingException e) {
// LOGGER.error("failed to send email", e);
// throw new IllegalStateException("failed to send email");
// }
try {
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper =
new MimeMessageHelper(mimeMessage, "utf-8");
helper.setText(email, true);
helper.setTo(to);
helper.setSubject("Confirm your email");
helper.setFrom("hello@amigoscode.com");
mailSender.send(mimeMessage);
} catch (MessagingException e) {
LOGGER.error("failed to send email", e);
throw new IllegalStateException("failed to send email");
}
System.out.println("Skipping email sending during development.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,16 @@ public interface ExamManagementService {
List<ConflictExamResponse> getExamsScheduledBetween(Long examId);

List<CandidateConflictExamResponse> getCandidateConflictingExams(Long examId);

GenericResponse updateRealTimeMonitoring(Long examId, RealTimeMonitoringRequest dto);
RealTimeMonitoringResponse getRealTimeMonitoringStatus(Long examId);

GenericResponse updateBrowserLockdown(Long examId, boolean browserLockdown);
boolean getBrowserLockdownStatus(Long examId);

GenericResponse updateHostedStatus(Long examId, boolean hosted);
boolean getHostedStatus(Long examId);

void assignModerator(Long examId, String moderatorEmail);
ModeratorResponse getModeratorDetails(Long examId);
}
Loading