Skip to content

Commit 930f491

Browse files
authored
Merge pull request #14 from UdL-EPS-SoftArch/Project
Project
2 parents 5bf7249 + 858c7da commit 930f491

6 files changed

Lines changed: 444 additions & 12 deletions

File tree

src/main/java/cat/udl/eps/softarch/demo/config/WebSecurityConfig.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,21 @@ public class WebSecurityConfig {
2626

2727
@Bean
2828
protected SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
29-
http.authorizeHttpRequests((auth) -> auth
30-
.requestMatchers(HttpMethod.GET, "/identity").authenticated()
31-
.requestMatchers(HttpMethod.GET, "/users").authenticated()
32-
.requestMatchers(HttpMethod.POST, "/users").anonymous()
33-
.requestMatchers(HttpMethod.POST, "/users/*").denyAll()
34-
.requestMatchers(HttpMethod.POST, "/*/*").authenticated()
35-
.requestMatchers(HttpMethod.PUT, "/*/*").authenticated()
36-
.requestMatchers(HttpMethod.PATCH, "/*/*").authenticated()
37-
.requestMatchers(HttpMethod.DELETE, "/*/*").authenticated()
38-
.requestMatchers(HttpMethod.GET, "/portfolios/search/findByVisibility").permitAll()
39-
.requestMatchers(HttpMethod.GET, "/portfolios/**").authenticated()
40-
.anyRequest().permitAll())
29+
http.authorizeHttpRequests((auth) -> auth
30+
.requestMatchers(HttpMethod.GET, "/identity").authenticated()
31+
.requestMatchers(HttpMethod.GET, "/users").authenticated()
32+
.requestMatchers(HttpMethod.POST, "/users").anonymous()
33+
.requestMatchers(HttpMethod.POST, "/users/*").denyAll()
34+
.requestMatchers(HttpMethod.POST, "/projects").authenticated()
35+
.requestMatchers(HttpMethod.PUT, "/projects/*").authenticated()
36+
.requestMatchers(HttpMethod.DELETE, "/projects/*").authenticated()
37+
.requestMatchers(HttpMethod.POST, "/*/*").authenticated()
38+
.requestMatchers(HttpMethod.PUT, "/*/*").authenticated()
39+
.requestMatchers(HttpMethod.PATCH, "/*/*").authenticated()
40+
.requestMatchers(HttpMethod.DELETE, "/*/*").authenticated()
41+
.requestMatchers(HttpMethod.GET, "/portfolios/search/findByVisibility").permitAll()
42+
.requestMatchers(HttpMethod.GET, "/portfolios/**").authenticated()
43+
.anyRequest().permitAll())
4144
.csrf((csrf) -> csrf.disable())
4245
.sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
4346
.cors((cors) -> cors.configurationSource(corsConfigurationSource()))
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package cat.udl.eps.softarch.demo.domain;
2+
3+
import jakarta.persistence.*;
4+
import jakarta.validation.constraints.NotBlank;
5+
import lombok.Data;
6+
import lombok.EqualsAndHashCode;
7+
import org.springframework.lang.Nullable;
8+
9+
import java.time.ZonedDateTime;
10+
11+
@Entity
12+
@Data
13+
@EqualsAndHashCode(callSuper = true)
14+
public class Project extends UriEntity<Long> {
15+
16+
@Id
17+
@GeneratedValue(strategy = GenerationType.IDENTITY)
18+
private Long id;
19+
20+
@NotBlank
21+
private String name;
22+
23+
private String description;
24+
25+
private ZonedDateTime created;
26+
27+
@Enumerated(EnumType.STRING)
28+
private Visibility visibility;
29+
30+
private ZonedDateTime modified;
31+
32+
// Relació amb Portfolio (segons el diagrama, un Project pertany a un Portfolio)
33+
//@ManyToOne
34+
//@JoinColumn(name = "portfolio_id")
35+
//private Portfolio portfolio;
36+
37+
public Project() {
38+
this.created = ZonedDateTime.now();
39+
}
40+
41+
@Nullable
42+
@Override
43+
public Long getId() {
44+
return this.id;
45+
}
46+
47+
public ZonedDateTime getCreated() { return this.created;}
48+
49+
public void setCreated(ZonedDateTime created) {
50+
this.created = created;
51+
}
52+
53+
public void setModified(ZonedDateTime modified) {
54+
this.modified = modified;
55+
}
56+
57+
public void setName(String name) {this.name = name;}
58+
59+
public void setDescription(String description) {this.description = description;}
60+
61+
//public void setPortfolio(Portfolio portfolio) {
62+
//this.portfolio = portfolio;
63+
//}
64+
65+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package cat.udl.eps.softarch.demo.handler;
2+
3+
import cat.udl.eps.softarch.demo.domain.Project;
4+
import cat.udl.eps.softarch.demo.repository.ProjectRepository;
5+
import org.springframework.data.rest.core.annotation.*;
6+
import org.springframework.stereotype.Component;
7+
8+
import java.time.ZonedDateTime;
9+
10+
@Component
11+
@RepositoryEventHandler
12+
public class ProjectEventHandler {
13+
final ProjectRepository projectRepository;
14+
15+
public ProjectEventHandler(ProjectRepository projectRepository) {
16+
this.projectRepository = projectRepository;
17+
}
18+
19+
@HandleBeforeCreate
20+
public void handleProjectPreCreate(Project project) {
21+
ZonedDateTime timeStamp = ZonedDateTime.now();
22+
project.setCreated(timeStamp);
23+
project.setModified(timeStamp);
24+
}
25+
26+
@HandleBeforeSave
27+
public void handleProjectPreSave(Project project) {
28+
ZonedDateTime timeStamp = ZonedDateTime.now();
29+
project.setModified(timeStamp);
30+
}
31+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package cat.udl.eps.softarch.demo.repository;
2+
3+
import cat.udl.eps.softarch.demo.domain.Project;
4+
import cat.udl.eps.softarch.demo.domain.User;
5+
import org.springframework.data.repository.CrudRepository;
6+
import org.springframework.data.repository.PagingAndSortingRepository;
7+
import org.springframework.data.repository.query.Param;
8+
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
9+
10+
import java.util.List;
11+
12+
@RepositoryRestResource
13+
public interface ProjectRepository extends CrudRepository<Project, Long>, PagingAndSortingRepository<Project, Long> {
14+
15+
List<Project> findByNameContaining(@Param("name") String name);
16+
17+
}
Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
package cat.udl.eps.softarch.demo.steps;
2+
3+
import cat.udl.eps.softarch.demo.domain.Project;
4+
import cat.udl.eps.softarch.demo.domain.Visibility;
5+
import cat.udl.eps.softarch.demo.repository.ProjectRepository;
6+
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
7+
import io.cucumber.java.en.And;
8+
import io.cucumber.java.en.Given;
9+
import io.cucumber.java.en.Then;
10+
import io.cucumber.java.en.When;
11+
import org.springframework.http.MediaType;
12+
13+
import java.nio.charset.StandardCharsets;
14+
15+
import static org.hamcrest.Matchers.hasItem;
16+
import static org.hamcrest.Matchers.is;
17+
import static org.hamcrest.Matchers.empty;
18+
import static org.hamcrest.Matchers.notNullValue;
19+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
20+
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
21+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
22+
23+
public class ManageProjectStepDefs {
24+
25+
private final StepDefs stepDefs;
26+
private final ProjectRepository projectRepository;
27+
private Project preparedProject;
28+
29+
public ManageProjectStepDefs(StepDefs stepDefs, ProjectRepository projectRepository) {
30+
this.stepDefs = stepDefs;
31+
this.projectRepository = projectRepository;
32+
this.stepDefs.mapper.registerModule(new JavaTimeModule());
33+
}
34+
35+
// ===================== GIVEN =====================
36+
37+
@Given("I prepare a project with name {string} and description {string} and visibility {string}")
38+
public void iPrepareAProject(String name, String description, String visibility) {
39+
preparedProject = new Project();
40+
preparedProject.setName(name);
41+
preparedProject.setDescription(description);
42+
preparedProject.setVisibility(Visibility.valueOf(visibility));
43+
}
44+
45+
@And("There is a project with name {string} and description {string} and visibility {string}")
46+
public void thereIsAProject(String name, String description, String visibility) {
47+
Project p = new Project();
48+
p.setName(name);
49+
p.setDescription(description);
50+
p.setVisibility(Visibility.valueOf(visibility));
51+
projectRepository.save(p);
52+
}
53+
54+
55+
// ===================== WHEN =====================
56+
57+
@When("I send the create project request")
58+
public void iSendTheCreateProjectRequest() throws Exception {
59+
stepDefs.result = stepDefs.mockMvc.perform(
60+
post("/projects")
61+
.contentType(MediaType.APPLICATION_JSON)
62+
.content(stepDefs.mapper.writeValueAsString(preparedProject))
63+
.characterEncoding(StandardCharsets.UTF_8)
64+
.accept(MediaType.APPLICATION_JSON)
65+
.with(AuthenticationStepDefs.authenticate()))
66+
.andDo(print());
67+
68+
if (stepDefs.result.andReturn().getResponse().getStatus() == 201) {
69+
String location = stepDefs.result.andReturn().getResponse().getHeader("Location");
70+
stepDefs.result = stepDefs.mockMvc.perform(
71+
get(location)
72+
.accept(MediaType.APPLICATION_JSON)
73+
.with(AuthenticationStepDefs.authenticate()))
74+
.andDo(print());
75+
}
76+
}
77+
78+
@When("I retrieve the project named {string}")
79+
public void iRetrieveTheProjectNamed(String name) throws Exception {
80+
Project found = projectRepository.findByNameContaining(name)
81+
.stream().filter(p -> p.getName().equals(name))
82+
.findFirst().orElseThrow();
83+
84+
stepDefs.result = stepDefs.mockMvc.perform(
85+
get("/projects/{id}", found.getId())
86+
.accept(MediaType.APPLICATION_JSON)
87+
.with(AuthenticationStepDefs.authenticate()))
88+
.andDo(print());
89+
}
90+
91+
@When("I retrieve the project with id {long}")
92+
public void iRetrieveTheProjectWithId(Long id) throws Exception {
93+
stepDefs.result = stepDefs.mockMvc.perform(
94+
get("/projects/{id}", id)
95+
.accept(MediaType.APPLICATION_JSON)
96+
.with(AuthenticationStepDefs.authenticate()))
97+
.andDo(print());
98+
}
99+
100+
@When("I update the project with id {long} setting name to {string}")
101+
public void iUpdateTheProjectWithIdSettingName(Long id, String newName) throws Exception {
102+
Project project = new Project();
103+
project.setName(newName);
104+
105+
stepDefs.result = stepDefs.mockMvc.perform(
106+
patch("/projects/{id}", id)
107+
.contentType(MediaType.APPLICATION_JSON)
108+
.content(stepDefs.mapper.writeValueAsString(project))
109+
.characterEncoding(StandardCharsets.UTF_8)
110+
.accept(MediaType.APPLICATION_JSON)
111+
.with(AuthenticationStepDefs.authenticate()))
112+
.andDo(print());
113+
}
114+
115+
@When("I update the project with id {long} setting visibility to {string}")
116+
public void iUpdateTheProjectWithIdSettingVisibility(Long id, String visibility) throws Exception {
117+
Project project = new Project();
118+
project.setVisibility(Visibility.valueOf(visibility));
119+
120+
stepDefs.result = stepDefs.mockMvc.perform(
121+
patch("/projects/{id}", id)
122+
.contentType(MediaType.APPLICATION_JSON)
123+
.content(stepDefs.mapper.writeValueAsString(project))
124+
.characterEncoding(StandardCharsets.UTF_8)
125+
.accept(MediaType.APPLICATION_JSON)
126+
.with(AuthenticationStepDefs.authenticate()))
127+
.andDo(print());
128+
}
129+
130+
@When("I update the project named {string} with new name {string}")
131+
public void iUpdateTheProjectNamed(String oldName, String newName) throws Exception {
132+
Project found = projectRepository.findByNameContaining(oldName)
133+
.stream().filter(p -> p.getName().equals(oldName))
134+
.findFirst().orElseThrow();
135+
136+
found.setName(newName);
137+
138+
stepDefs.result = stepDefs.mockMvc.perform(
139+
put("/projects/{id}", found.getId())
140+
.contentType(MediaType.APPLICATION_JSON)
141+
.content(stepDefs.mapper.writeValueAsString(found))
142+
.characterEncoding(StandardCharsets.UTF_8)
143+
.accept(MediaType.APPLICATION_JSON)
144+
.with(AuthenticationStepDefs.authenticate()))
145+
.andDo(print());
146+
}
147+
148+
149+
@When("I update the project named {string} setting visibility to {string}")
150+
public void iUpdateTheProjectVisibility(String name, String visibility) throws Exception {
151+
Project found = projectRepository.findByNameContaining(name)
152+
.stream().filter(p -> p.getName().equals(name))
153+
.findFirst().orElseThrow();
154+
155+
found.setVisibility(Visibility.valueOf(visibility));
156+
157+
stepDefs.result = stepDefs.mockMvc.perform(
158+
put("/projects/{id}", found.getId())
159+
.contentType(MediaType.APPLICATION_JSON)
160+
.content(stepDefs.mapper.writeValueAsString(found))
161+
.characterEncoding(StandardCharsets.UTF_8)
162+
.accept(MediaType.APPLICATION_JSON)
163+
.with(AuthenticationStepDefs.authenticate()))
164+
.andDo(print());
165+
}
166+
167+
168+
@When("I retrieve the list of projects")
169+
public void iRetrieveTheListOfProjects() throws Exception {
170+
stepDefs.result = stepDefs.mockMvc.perform(
171+
get("/projects")
172+
.accept(MediaType.APPLICATION_JSON)
173+
.with(AuthenticationStepDefs.authenticate()))
174+
.andDo(print());
175+
}
176+
177+
@When("I delete the project named {string}")
178+
public void iDeleteTheProjectNamed(String name) throws Exception {
179+
Project found = projectRepository.findByNameContaining(name)
180+
.stream().filter(p -> p.getName().equals(name))
181+
.findFirst().orElseThrow();
182+
183+
stepDefs.result = stepDefs.mockMvc.perform(
184+
delete("/projects/{id}", found.getId())
185+
.with(AuthenticationStepDefs.authenticate()))
186+
.andDo(print());
187+
}
188+
189+
@When("I delete the project with id {long}")
190+
public void iDeleteTheProjectWithId(Long id) throws Exception {
191+
stepDefs.result = stepDefs.mockMvc.perform(
192+
delete("/projects/{id}", id)
193+
.with(AuthenticationStepDefs.authenticate()))
194+
.andDo(print());
195+
}
196+
197+
// ===================== THEN / AND =====================
198+
199+
@Then("The project name is {string}")
200+
public void theProjectNameIs(String name) throws Exception {
201+
stepDefs.result.andExpect(jsonPath("$.name", is(name)));
202+
}
203+
204+
@Then("The project creation date should be set")
205+
public void theProjectCreationDateShouldBeSet() throws Exception {
206+
stepDefs.result.andExpect(jsonPath("$.created", notNullValue()));
207+
}
208+
209+
210+
@Then("The project modification date should be set")
211+
public void theProjectModificationDateShouldBeSet() throws Exception {
212+
stepDefs.result.andExpect(jsonPath("$.modified", notNullValue()));
213+
}
214+
215+
@Then("The project list contains a project named {string}")
216+
public void theProjectListContainsAProjectNamed(String name) throws Exception {
217+
stepDefs.result.andExpect(
218+
jsonPath("$._embedded.projects[*].name", hasItem(is(name)))
219+
);
220+
}
221+
222+
@Then("The project visibility should be {string}")
223+
public void theProjectVisibilityShouldBe(String visibility) throws Exception {
224+
stepDefs.result.andExpect(jsonPath("$.visibility", is(visibility)));
225+
}
226+
227+
@Then("The project list is empty")
228+
public void theProjectListIsEmpty() throws Exception {
229+
stepDefs.result.andExpect(jsonPath("$._embedded.projects", empty()));
230+
}
231+
232+
233+
}

0 commit comments

Comments
 (0)