Merge pull request 'chore: Update branch' (#10) from Maradona/Backend:restfull into main
Reviewed-on: 3001291/Backend#10pull/1/head
commit
cf608ceb28
|
@ -31,3 +31,11 @@ build/
|
|||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
.history/
|
||||
|
||||
### macOS ###
|
||||
*.DS_Store
|
||||
|
||||
### Database files ###
|
||||
*.db
|
||||
*.mv.db
|
||||
|
|
Binary file not shown.
1
pom.xml
1
pom.xml
|
@ -102,6 +102,7 @@
|
|||
<destDir>${project.build.directory}/docs</destDir>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
@ -33,13 +33,13 @@ public class DefaultValueLoader implements CommandLineRunner {
|
|||
private FormOfAddressRepository formOfAddressRepository;
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
public void run(String... args) {
|
||||
|
||||
// Clear all tables
|
||||
// formOfAddressRepository.deleteAll();
|
||||
// employeeRepository.deleteAll();
|
||||
// secondarySkillRepository.deleteAll();
|
||||
// primarySkillRepository.deleteAll();
|
||||
employeeRepository.deleteAll();
|
||||
secondarySkillRepository.deleteAll();
|
||||
primarySkillRepository.deleteAll();
|
||||
formOfAddressRepository.deleteAll();
|
||||
|
||||
// Create form of addresses
|
||||
FormOfAddress formOfAddress1 = new FormOfAddress();
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
package com.maradona.backend.controllers.api;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.maradona.backend.entities.FormOfAddress;
|
||||
import com.maradona.backend.services.FormOfAddressService;
|
||||
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
|
||||
/**
|
||||
* Controller for routing to the form of address related API endpoints.
|
||||
*
|
||||
* List of endpoints:
|
||||
* - GET /api/form-of-adress
|
||||
* - GET /api/form-of-adress/all
|
||||
* - POST /api/form-of-adress
|
||||
* - PUT /api/form-of-adress
|
||||
* - DELETE /api/form-of-adress
|
||||
*
|
||||
* @see com.maradona.backend.entities.FormOfAddress
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/form-of-adress")
|
||||
class FormOfAdressController {
|
||||
|
||||
@Autowired
|
||||
private FormOfAddressService formOfAdressService;
|
||||
|
||||
/**
|
||||
* Returns the form of address with the given ID.
|
||||
*
|
||||
* @param id The ID of the form of address to return.
|
||||
* @return The description of the form of address with the given ID.
|
||||
* @see com.maradona.backend.entities.FormOfAddress
|
||||
*/
|
||||
@GetMapping({ "/", "" })
|
||||
public ResponseEntity<FormOfAddress> getFormOfAdress(@RequestParam Long id) {
|
||||
return formOfAdressService.getFormOfAddressById(id)
|
||||
.map(ResponseEntity::ok)
|
||||
.orElse(ResponseEntity.notFound().build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all form of addresses.
|
||||
*
|
||||
* @return A list of all form of addresses.
|
||||
* @see com.maradona.backend.entities.FormOfAddress
|
||||
*/
|
||||
@GetMapping("/all")
|
||||
public ResponseEntity<Iterable<FormOfAddress>> getAllFormOfAdresses() {
|
||||
Iterable<FormOfAddress> formOfAddresses = formOfAdressService.getAllFormOfAddresses();
|
||||
return ResponseEntity.ok(formOfAddresses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new form of address.
|
||||
*
|
||||
* @param description The description of the new form of address.
|
||||
* @return The ID of the newly created form of address.
|
||||
* @see com.maradona.backend.entities.FormOfAddress
|
||||
*/
|
||||
@PostMapping({ "/", "" })
|
||||
public ResponseEntity<Void> createFormOfAdress(@RequestBody String description) {
|
||||
var formOfAddress = new FormOfAddress();
|
||||
formOfAddress.setDescription(description);
|
||||
formOfAdressService.saveFormOfAddress(formOfAddress);
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the description of a form of address.
|
||||
*
|
||||
* @param id The ID of the form of address to update.
|
||||
* @param description The new description of the form of address.
|
||||
* @return The updated form of address.
|
||||
* @see com.maradona.backend.entities.FormOfAddress
|
||||
*/
|
||||
@PutMapping({ "/", "" })
|
||||
public ResponseEntity<Void> updateFormOfAdress(@RequestParam Long id, @RequestBody String description) {
|
||||
var formOfAddress = formOfAdressService.getFormOfAddressById(id).orElse(null);
|
||||
if (formOfAddress == null) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
formOfAddress.setDescription(description);
|
||||
formOfAdressService.saveFormOfAddress(formOfAddress);
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a form of address.
|
||||
*
|
||||
* @param id The ID of the form of address to delete.
|
||||
* @return The deleted form of address.
|
||||
* @see com.maradona.backend.entities.FormOfAddress
|
||||
*/
|
||||
@DeleteMapping({ "/", "" })
|
||||
public ResponseEntity<Void> deleteFormOfAdress(@RequestParam Long id) {
|
||||
var formOfAddress = formOfAdressService.getFormOfAddressById(id).orElse(null);
|
||||
if (formOfAddress == null) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
formOfAdressService.deleteFormOfAddress(id);
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
}
|
|
@ -28,7 +28,6 @@ import com.maradona.backend.services.ProjectService;
|
|||
* - PUT /api/project
|
||||
* - DELETE /api/project
|
||||
*
|
||||
* @warning The ProjectService is not accounting for the user yet.
|
||||
* @see com.maradona.backend.entities.Project
|
||||
* @see com.maradona.backend.services.ProjectService
|
||||
*/
|
||||
|
|
|
@ -9,21 +9,21 @@ public class Page {
|
|||
|
||||
@GetMapping({ "/", "" })
|
||||
public String home(Model model) {
|
||||
return "redirect:/projects";
|
||||
return "pages/core/home";
|
||||
}
|
||||
|
||||
@GetMapping("/impressum")
|
||||
public String impressum() {
|
||||
return "core/impressum";
|
||||
return "pages/core/impressum";
|
||||
}
|
||||
|
||||
@GetMapping("/datenschutz")
|
||||
public String datenschutz() {
|
||||
return "core/datenschutz";
|
||||
return "pages/core/datenschutz";
|
||||
}
|
||||
|
||||
@GetMapping("/notes")
|
||||
public String notes() {
|
||||
return "notes/notes";
|
||||
return "pages/core/notes";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import com.maradona.backend.services.ProjectService;
|
|||
* - GET /projects
|
||||
* - GET /projects/create
|
||||
*
|
||||
* @see Project
|
||||
* @see com.maradona.backend.entities.Project
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/projects")
|
||||
|
@ -32,13 +32,13 @@ public class ProjectPage {
|
|||
*
|
||||
* @param model The model with the data to be displayed.
|
||||
* @return The projects overview page template
|
||||
* @see Project
|
||||
* @see com.maradona.backend.entities.Project
|
||||
*/
|
||||
@GetMapping({ "/", "" })
|
||||
public String projects(Model model) {
|
||||
var projects = projectService.getAllProjects();
|
||||
model.addAttribute("projects", projects);
|
||||
return "projects/projects";
|
||||
return "/pages/projects/overview";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,11 +46,11 @@ public class ProjectPage {
|
|||
*
|
||||
* @param model The model with the data to be displayed.
|
||||
* @return The project creation page template
|
||||
* @see Project
|
||||
* @see com.maradona.backend.entities.Project
|
||||
*/
|
||||
@GetMapping("/create")
|
||||
public String create(Model model) {
|
||||
model.addAttribute("project", new Project());
|
||||
return "projects/projects-create";
|
||||
return "/pages/projects/create";
|
||||
}
|
||||
}
|
|
@ -7,8 +7,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||
import org.springframework.stereotype.Controller;
|
||||
|
||||
import com.maradona.backend.entities.SecondarySkill;
|
||||
import com.maradona.backend.entities.Employee;
|
||||
import com.maradona.backend.entities.PrimarySkill;
|
||||
import com.maradona.backend.services.EmployeeService;
|
||||
import com.maradona.backend.services.SkillService;
|
||||
import com.maradona.backend.services.PrimarySkillService;
|
||||
|
@ -22,6 +20,7 @@ import com.maradona.backend.dto.SkillPrototype;
|
|||
* - GET /skills/create
|
||||
* - GET /skills/add
|
||||
*
|
||||
* @see com.maradona.backend.entities.SecondarySkill
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/skills")
|
||||
|
@ -47,15 +46,15 @@ public class SkillsPage {
|
|||
* "employee" and a SkillsDto object "skills".
|
||||
*
|
||||
* @param model The model with the data to be displayed.
|
||||
* @return The skills overview page template
|
||||
* @see Employee
|
||||
* @see SkillsDto
|
||||
* @return The skills overview page template.
|
||||
* @see com.maradona.backend.entities.Employee
|
||||
* @see com.maradona.backend.dto.SkillsDto
|
||||
*/
|
||||
@GetMapping({ "/", "" })
|
||||
public String profile(Model model) {
|
||||
model.addAttribute("employee", employeeService.getEmployeeById(user).orElse(null));
|
||||
model.addAttribute("skills", skillService.getUserSkills(user));
|
||||
return "skills/skills";
|
||||
return "/pages/skills/overview";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,12 +65,12 @@ public class SkillsPage {
|
|||
*
|
||||
* @param model The model with the data to be displayed
|
||||
* @return The create skill page template
|
||||
* @see SecondarySkill
|
||||
* @see com.maradona.backend.entities.SecondarySkill
|
||||
*/
|
||||
@GetMapping("/create")
|
||||
public String createSkill(Model model) {
|
||||
model.addAttribute("secondarySkill", new SecondarySkill());
|
||||
return "skills/skills-create";
|
||||
return "/pages/skills/create";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,16 +86,16 @@ public class SkillsPage {
|
|||
*
|
||||
* @param model The model with the data to be displayed
|
||||
* @return The add skill page template
|
||||
* @see PrimarySkill
|
||||
* @see SecondarySkill
|
||||
* @see SkillPrototype
|
||||
* @see com.maradona.backend.entities.PrimarySkill
|
||||
* @see com.maradona.backend.entities.SecondarySkill
|
||||
* @see com.maradona.backend.dto.SkillPrototype
|
||||
*/
|
||||
@GetMapping("/add")
|
||||
public String addSkill(Model model) {
|
||||
// TODO: Make sure it returns the correct initail data for secondary skills
|
||||
model.addAttribute("primarySkills", primarySkillService.getAllPrimarySkills());
|
||||
model.addAttribute("skillProtoype", new SkillPrototype());
|
||||
return "skills/skills-add";
|
||||
return "/pages/skills/add";
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.maradona.backend.entities;
|
|||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonManagedReference;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -10,7 +11,6 @@ import java.util.stream.Collectors;
|
|||
@Entity
|
||||
@Data
|
||||
public class Employee {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
@ -31,6 +31,7 @@ public class Employee {
|
|||
private LocalTime dEnd;
|
||||
|
||||
@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||
@JsonManagedReference
|
||||
private List<EmployeeSecondarySkill> secondarySkills;
|
||||
|
||||
public void setEmployeeNr(Integer employeeNr) {
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
package com.maradona.backend.entities;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import com.fasterxml.jackson.annotation.JsonBackReference;
|
||||
import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonBackReference;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
public class EmployeeSecondarySkill {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
@ -19,7 +18,6 @@ public class EmployeeSecondarySkill {
|
|||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "secondary_skill_id", nullable = false)
|
||||
@JsonBackReference
|
||||
private SecondarySkill secondarySkill;
|
||||
|
||||
@Column(nullable = false)
|
||||
|
|
|
@ -28,4 +28,14 @@ public class FormOfAddressService {
|
|||
public Iterable<FormOfAddress> getAllFormOfAddresses() {
|
||||
return formOfAddressRepository.findAll();
|
||||
}
|
||||
|
||||
public Long updateFormOfAddress(Long id, String description) {
|
||||
var formOfAddress = formOfAddressRepository.findById(id).orElse(null);
|
||||
if (formOfAddress != null) {
|
||||
formOfAddress.setDescription(description);
|
||||
formOfAddressRepository.save(formOfAddress);
|
||||
return id;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
document.getElementById("primarySkill").addEventListener("change", function () {
|
||||
var primarySkillId = this.value;
|
||||
fetch("/skills/secondary-skills?primarySkillId=" + primarySkillId)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
console.log("Fetch response data:", data);
|
||||
var secondarySkillSelect = document.getElementById("secondarySkill");
|
||||
secondarySkillSelect.innerHTML =
|
||||
'<option value="" disabled selected>Select a secondary skill</option>';
|
||||
data.forEach(function (secondarySkill) {
|
||||
var option = document.createElement("option");
|
||||
option.value = secondarySkill.ssid;
|
||||
option.text = secondarySkill.description;
|
||||
secondarySkillSelect.add(option);
|
||||
});
|
||||
})
|
||||
.catch((error) => console.error("Error fetching secondary skills:", error));
|
||||
});
|
|
@ -1 +0,0 @@
|
|||
/* Placeholder */
|
|
@ -5,26 +5,9 @@
|
|||
<img src="/assets/inter-brand.svg" alt="INTER Logo" class="svg-logo" />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<nav>
|
||||
<ul class="nav justify-content-end">
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link"
|
||||
th:href="@{/projects}"
|
||||
th:classappend="${activePage == 'projects' ? 'active' : ''}"
|
||||
>Projekte</a
|
||||
>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link"
|
||||
th:href="@{/skills}"
|
||||
th:classappend="${activePage == 'profile' ? 'active' : ''}"
|
||||
>Skills</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div
|
||||
th:replace="~{/core/_navigation :: navigation(activePage=${activePage})}"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<div th:fragment="navigation">
|
||||
<nav>
|
||||
<ul class="nav justify-content-end">
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link"
|
||||
th:href="@{/projects}"
|
||||
th:classappend="${activePage == 'projects' ? 'active' : ''}"
|
||||
>Projekte</a
|
||||
>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link"
|
||||
th:href="@{/skills}"
|
||||
th:classappend="${activePage == 'profile' ? 'active' : ''}"
|
||||
>Skills</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
|
@ -1,15 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<div th:replace="~{/core/_metadata :: metadata}"></div>
|
||||
<title>My Skill Management System</title>
|
||||
<link rel="stylesheet" href="style/notes/notes.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<div th:replace="~{/core/_header :: header(activePage=${notes})}"></div>
|
||||
<div class="content container mt-4"></div>
|
||||
<div th:replace="~{/core/_footer :: footer}"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -3,10 +3,10 @@
|
|||
<head>
|
||||
<div th:replace="~{/core/_metadata :: metadata}"></div>
|
||||
<title>Create Project</title>
|
||||
<link rel="stylesheet" href="/style/projects/projects.css" />
|
||||
<link rel="stylesheet" href="/style/core/style.css" />
|
||||
<link rel="stylesheet" href="/style/core/header.css" />
|
||||
<link rel="stylesheet" href="/style/core/footer.css" />
|
||||
<link rel="stylesheet" href="/css/projects/projects.css" />
|
||||
<link rel="stylesheet" href="/css/core/style.css" />
|
||||
<link rel="stylesheet" href="/css/core/header.css" />
|
||||
<link rel="stylesheet" href="/css/core/footer.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
|
@ -3,7 +3,10 @@
|
|||
<head>
|
||||
<div th:replace="~{/core/_metadata :: metadata}"></div>
|
||||
<title>Projects</title>
|
||||
<link rel="stylesheet" href="/style/projects/projects.css" />
|
||||
<link rel="stylesheet" href="/css/projects/projects.css" />
|
||||
<link rel="stylesheet" href="/css/core/style.css" />
|
||||
<link rel="stylesheet" href="/css/core/header.css" />
|
||||
<link rel="stylesheet" href="/css/core/footer.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
|
@ -3,10 +3,10 @@
|
|||
<head>
|
||||
<div th:replace="~{/core/_metadata :: metadata}"></div>
|
||||
<title>Add Skill</title>
|
||||
<link rel="stylesheet" href="/style/skills/skills.css" />
|
||||
<link rel="stylesheet" href="/style/core/style.css" />
|
||||
<link rel="stylesheet" href="/style/core/header.css" />
|
||||
<link rel="stylesheet" href="/style/core/footer.css" />
|
||||
<link rel="stylesheet" href="/css/skills/skills.css" />
|
||||
<link rel="stylesheet" href="/css/core/style.css" />
|
||||
<link rel="stylesheet" href="/css/core/header.css" />
|
||||
<link rel="stylesheet" href="/css/core/footer.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
|
@ -15,11 +15,12 @@
|
|||
<h2 class="mb-4">Add Skill</h2>
|
||||
<form
|
||||
th:action="@{/skills/add}"
|
||||
th:object="${skillForm}"
|
||||
th:object="${skillProtoype}"
|
||||
method="post"
|
||||
class="project-card"
|
||||
>
|
||||
<div class="card-body">
|
||||
<!-- Primary Skill Dropdown -->
|
||||
<div class="form-group">
|
||||
<label for="primarySkill">Primary Skill</label>
|
||||
<select
|
||||
|
@ -28,6 +29,9 @@
|
|||
class="form-control"
|
||||
th:field="*{primarySkillId}"
|
||||
>
|
||||
<option value="" disabled selected>
|
||||
Select a primary skill
|
||||
</option>
|
||||
<option
|
||||
th:each="primarySkill : ${primarySkills}"
|
||||
th:value="${primarySkill.psid}"
|
||||
|
@ -35,6 +39,8 @@
|
|||
></option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Secondary Skill Dropdown -->
|
||||
<div class="form-group">
|
||||
<label for="secondarySkill">Secondary Skill</label>
|
||||
<select
|
||||
|
@ -48,6 +54,8 @@
|
|||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Skill Level Dropdown -->
|
||||
<div class="form-group">
|
||||
<label for="level">Level</label>
|
||||
<select
|
||||
|
@ -56,6 +64,7 @@
|
|||
class="form-control"
|
||||
th:field="*{level}"
|
||||
>
|
||||
<option value="" disabled selected>Select skill level</option>
|
||||
<option
|
||||
th:each="level : ${#numbers.sequence(1, 5)}"
|
||||
th:value="${level}"
|
||||
|
@ -63,36 +72,14 @@
|
|||
></option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<button type="submit" class="btn-create-project">Add Skill</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div th:replace="~{/core/_footer :: footer}"></div>
|
||||
</div>
|
||||
<script>
|
||||
document
|
||||
.getElementById("primarySkill")
|
||||
.addEventListener("change", function () {
|
||||
var primarySkillId = this.value;
|
||||
fetch("/skills/secondary-skills?primarySkillId=" + primarySkillId)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
console.log("Fetch response data:", data);
|
||||
var secondarySkillSelect =
|
||||
document.getElementById("secondarySkill");
|
||||
secondarySkillSelect.innerHTML =
|
||||
'<option value="" disabled selected>Select a secondary skill</option>';
|
||||
data.forEach(function (secondarySkill) {
|
||||
var option = document.createElement("option");
|
||||
option.value = secondarySkill.ssid;
|
||||
option.text = secondarySkill.description;
|
||||
secondarySkillSelect.add(option);
|
||||
});
|
||||
})
|
||||
.catch((error) =>
|
||||
console.error("Error fetching secondary skills:", error)
|
||||
);
|
||||
});
|
||||
</script>
|
||||
<script src="/js/skills/fetchSecondarySkills.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -3,10 +3,10 @@
|
|||
<head>
|
||||
<div th:replace="~{/core/_metadata :: metadata}"></div>
|
||||
<title>Create Skill</title>
|
||||
<link rel="stylesheet" href="/style/skills/skills.css" />
|
||||
<link rel="stylesheet" href="/style/core/style.css" />
|
||||
<link rel="stylesheet" href="/style/core/header.css" />
|
||||
<link rel="stylesheet" href="/style/core/footer.css" />
|
||||
<link rel="stylesheet" href="/css/skills/skills.css" />
|
||||
<link rel="stylesheet" href="/css/core/style.css" />
|
||||
<link rel="stylesheet" href="/css/core/header.css" />
|
||||
<link rel="stylesheet" href="/css/core/footer.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
|
@ -3,8 +3,10 @@
|
|||
<head>
|
||||
<div th:replace="~{/core/_metadata :: metadata}"></div>
|
||||
<title>Skills</title>
|
||||
<link rel="stylesheet" href="/style/skills/skills.css" />
|
||||
<link rel="stylesheet" href="/style/core/style.css" />
|
||||
<link rel="stylesheet" href="/css/skills/skills.css" />
|
||||
<link rel="stylesheet" href="/css/core/style.css" />
|
||||
<link rel="stylesheet" href="/css/core/header.css" />
|
||||
<link rel="stylesheet" href="/css/core/footer.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
|
@ -0,0 +1,57 @@
|
|||
package com.maradona.backend.controllers.api;
|
||||
|
||||
import com.maradona.backend.controllers.api.EmployeeController;
|
||||
import com.maradona.backend.entities.Employee;
|
||||
import com.maradona.backend.services.EmployeeService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import java.time.LocalTime;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
|
||||
@WebMvcTest(EmployeeController.class)
|
||||
public class EmployeeControllerTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@MockBean
|
||||
private EmployeeService employeeService;
|
||||
|
||||
@Test
|
||||
public void testGetEmployeeById() throws Exception {
|
||||
// Arrange: Mock an employee
|
||||
Employee employee = new Employee();
|
||||
employee.setId(1L);
|
||||
employee.setEmployeeNr(123);
|
||||
employee.setFirstName("John");
|
||||
employee.setLastName("Doe");
|
||||
employee.setDStart(LocalTime.of(9, 0));
|
||||
employee.setDEnd(LocalTime.of(17, 0));
|
||||
|
||||
// Assuming FormOfAddress and EmployeeSecondarySkill are also set up if needed for your test.
|
||||
|
||||
when(employeeService.getEmployeeById(1L)).thenReturn(Optional.of(employee));
|
||||
|
||||
// Act & Assert: Send GET request and expect a 200 OK status and JSON response
|
||||
mockMvc.perform(get("/api/employee")
|
||||
.param("id", "1")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.id").value(1))
|
||||
.andExpect(jsonPath("$.employeeNr").value(123))
|
||||
.andExpect(jsonPath("$.firstName").value("John"))
|
||||
.andExpect(jsonPath("$.lastName").value("Doe"))
|
||||
.andExpect(jsonPath("$.dStart").value("09:00:00"))
|
||||
.andExpect(jsonPath("$.dEnd").value("17:00:00"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,199 @@
|
|||
package com.maradona.backend.controllers.api;
|
||||
|
||||
import com.maradona.backend.controllers.api.ProjectController;
|
||||
import com.maradona.backend.entities.Project;
|
||||
import com.maradona.backend.services.ProjectService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
|
||||
@WebMvcTest(ProjectController.class)
|
||||
public class ProjectControllerTest {
|
||||
// MockMvc to simulate HTTP requests to the controller
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
// Mocked ProjectService to simulate service calls
|
||||
@MockBean
|
||||
private ProjectService projectService;
|
||||
|
||||
@Test
|
||||
public void testGetProjectById() throws Exception {
|
||||
//Arrange: Mock an project
|
||||
Project project = new Project();
|
||||
project.setId(1L);
|
||||
project.setName("Skillmanagementsystem erstellen");
|
||||
project.setStartDate(LocalDate.of(2024, 11,8));
|
||||
project.setEndDate(LocalDate.of(2024, 11,20));
|
||||
project.setWorkload(12);
|
||||
project.setDescription("Skillmanagementsystem erstellen für die Firma");
|
||||
|
||||
//Define the behavior of the mocked ProjectService: return the project when ID 1 is requested
|
||||
when(projectService.getProjectById(1L)).thenReturn(Optional.of(project));
|
||||
|
||||
//Act & Assert: Send GET request an expect a 200 OK status and JSON response
|
||||
//GET /api/project/
|
||||
mockMvc.perform(get("/api/project")
|
||||
.param("id", "1")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.id").value(1))
|
||||
.andExpect(jsonPath("$.name").value("Skillmanagementsystem erstellen"))
|
||||
.andExpect(jsonPath("$.startDate").value("2024-11-08"))
|
||||
.andExpect(jsonPath("$.endDate").value("2024-11-20"))
|
||||
.andExpect(jsonPath("$.workload").value(12))
|
||||
.andExpect(jsonPath("$.description").value("Skillmanagementsystem erstellen für die Firma"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAllProjects() throws Exception {
|
||||
//Arrange: Creat a list of mock projects
|
||||
Project project = new Project();
|
||||
project.setId(1L);
|
||||
project.setName("Skillmanagementsystem erstellen");
|
||||
project.setStartDate(LocalDate.of(2024, 11,8));
|
||||
project.setEndDate(LocalDate.of(2024, 11,20));
|
||||
project.setWorkload(12);
|
||||
project.setDescription("Skillmanagementsystem erstellen für die Firma");
|
||||
|
||||
Project project2 = new Project();
|
||||
project2.setId(2L);
|
||||
project2.setName("EAFC 25");
|
||||
project2.setStartDate(LocalDate.of(2024, 11,20));
|
||||
project2.setEndDate(LocalDate.of(2024, 11,30));
|
||||
project2.setWorkload(2);
|
||||
project2.setDescription("Entwicklung von EAFC 25 für neues Spaß erlebnis");
|
||||
|
||||
//Define the behavior of the mocked ProjectService: return a list of projects when requested
|
||||
when(projectService.getAllProjects()).thenReturn(Arrays.asList(project, project2));
|
||||
|
||||
//Act & Assert: Send GET request an expect a 200 Ok status and JSON response with the list of projects
|
||||
mockMvc.perform(get("/api/project/all")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$[0].id").value(1))
|
||||
.andExpect(jsonPath("$[0].name").value("Skillmanagementsystem erstellen"))
|
||||
.andExpect(jsonPath("$[0].startDate").value("2024-11-08"))
|
||||
.andExpect(jsonPath("$[0].endDate").value("2024-11-20"))
|
||||
.andExpect(jsonPath("$[0].workload").value(12))
|
||||
.andExpect(jsonPath("$[0].description").value("Skillmanagementsystem erstellen für die Firma"))
|
||||
.andExpect(jsonPath("$[1].id").value(2))
|
||||
.andExpect(jsonPath("$[1].name").value("EAFC 25"))
|
||||
.andExpect(jsonPath("$[1].startDate").value("2024-11-20"))
|
||||
.andExpect(jsonPath("$[1].endDate").value("2024-11-30"))
|
||||
.andExpect(jsonPath("$[1].workload").value(2))
|
||||
.andExpect(jsonPath("$[1].description").value("Entwicklung von EAFC 25 für neues Spaß erlebnis"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetProjectsByUserId() throws Exception {
|
||||
// Arrange: Mock projects for a specific user
|
||||
Project project1 = new Project();
|
||||
project1.setId(1L);
|
||||
project1.setName("Skill Management System");
|
||||
project1.setStartDate(LocalDate.of(2024, 11, 8));
|
||||
project1.setEndDate(LocalDate.of(2024, 11, 20));
|
||||
project1.setWorkload(12);
|
||||
project1.setDescription("Create a skill management system for the company");
|
||||
|
||||
Project project2 = new Project();
|
||||
project2.setId(2L);
|
||||
project2.setName("Project Management Tool");
|
||||
project2.setStartDate(LocalDate.of(2024, 12, 1));
|
||||
project2.setEndDate(LocalDate.of(2024, 12, 15));
|
||||
project2.setWorkload(10);
|
||||
project2.setDescription("Develop a project management tool");
|
||||
|
||||
Long userId = 123L;
|
||||
|
||||
// Mock the ProjectService to return projects for a specific user
|
||||
when(projectService.getProjectsByUserId(userId)).thenReturn(Arrays.asList(project1, project2));
|
||||
|
||||
// Act & Assert: Send GET request and expect a 200 OK status with the correct JSON response
|
||||
mockMvc.perform(get("/api/project/from-user")
|
||||
.param("userId", String.valueOf(userId))
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$[0].id").value(1))
|
||||
.andExpect(jsonPath("$[0].name").value("Skill Management System"))
|
||||
.andExpect(jsonPath("$[1].id").value(2))
|
||||
.andExpect(jsonPath("$[1].name").value("Project Management Tool"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateProject() throws Exception {
|
||||
// Arrange: Create a new project and set all required fields
|
||||
Project savedProject = new Project();
|
||||
savedProject.setId(1L); // ID setzen
|
||||
savedProject.setName("New Project");
|
||||
savedProject.setStartDate(LocalDate.of(2024, 11, 10));
|
||||
savedProject.setEndDate(LocalDate.of(2024, 12, 10));
|
||||
savedProject.setWorkload(15);
|
||||
savedProject.setDescription("A new project for testing");
|
||||
|
||||
// Mocking the saveProject method to return this specific project
|
||||
when(projectService.saveProject(any(Project.class))).thenReturn(savedProject);
|
||||
|
||||
// Act & Assert: Send POST request and check for 201 Created with JSON response
|
||||
mockMvc.perform(post("/api/project")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{\"name\":\"New Project\",\"startDate\":\"2024-11-10\",\"endDate\":\"2024-12-10\",\"workload\":15,\"description\":\"A new project for testing\"}"))
|
||||
.andExpect(status().isCreated())
|
||||
.andExpect(jsonPath("$.id").value(1)) // Ensure the response JSON contains id = 1
|
||||
.andExpect(jsonPath("$.name").value("New Project"))
|
||||
.andExpect(jsonPath("$.workload").value(15))
|
||||
.andExpect(jsonPath("$.description").value("A new project for testing"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateProject() throws Exception {
|
||||
// Arrange: Create an existing project
|
||||
Project project = new Project();
|
||||
project.setId(1L);
|
||||
project.setName("Updated Project");
|
||||
project.setStartDate(LocalDate.of(2024, 11, 10));
|
||||
project.setEndDate(LocalDate.of(2024, 12, 10));
|
||||
project.setWorkload(20);
|
||||
project.setDescription("An updated project description");
|
||||
|
||||
// Mock the ProjectService to return the updated project
|
||||
when(projectService.saveProject(project)).thenReturn(project);
|
||||
|
||||
// Act & Assert: Send PUT request and expect a 200 OK status with the updated project as JSON response
|
||||
mockMvc.perform(put("/api/project")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{\"id\":1,\"name\":\"Updated Project\",\"startDate\":\"2024-11-10\",\"endDate\":\"2024-12-10\",\"workload\":20,\"description\":\"An updated project description\"}"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.id").value(1))
|
||||
.andExpect(jsonPath("$.name").value("Updated Project"))
|
||||
.andExpect(jsonPath("$.workload").value(20))
|
||||
.andExpect(jsonPath("$.description").value("An updated project description"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteProject() throws Exception {
|
||||
// Arrange: Define the ID of the project to delete
|
||||
Long projectId = 1L;
|
||||
|
||||
// No need to mock the delete method as it returns void, we just ensure no exception is thrown
|
||||
|
||||
// Act & Assert: Send DELETE request and expect a 204 No Content status
|
||||
mockMvc.perform(delete("/api/project")
|
||||
.param("id", String.valueOf(projectId))
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isNoContent());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue