Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
096e6bf
add bug on purpose on the get all users endpoint
bitcoder Apr 4, 2024
9767945
Merge branch 'main' into dummy_feature
bitcoder Apr 5, 2024
e6b440c
ST-2 fix listing of all users
bitcoder Apr 5, 2024
6e30671
ST-2 add bug on purpose (again)
bitcoder Apr 5, 2024
71a9a43
Merge branch 'main' into dummy_feature
bitcoder Apr 5, 2024
0486c8c
ST-2 add bug on purpose
bitcoder Apr 8, 2024
ce4e552
ST-2 bug on purpose ..
bitcoder Apr 8, 2024
ec493bf
ST-2 fix dummy bug
bitcoder Apr 8, 2024
402cd8a
ST-2 bug on purpose
bitcoder Apr 9, 2024
b61e32e
ST-2 fix bug
bitcoder Apr 9, 2024
79a2b84
Update maven.yml
bitcoder May 2, 2025
1edf82e
Update maven.yml
bitcoder May 3, 2025
305f3b8
Update maven.yml
bitcoder May 3, 2025
4d1a6bf
Merge branch 'main' into dummy_feature
bitcoder May 3, 2025
54ddb58
remove failsafe: prefix from mvn command
bitcoder May 4, 2025
61a1890
additional unit testfor user repository
bitcoder May 4, 2025
fa282a4
additional unit tests for user service
bitcoder May 4, 2025
e1fb5e8
ST-2 bug on purpose
bitcoder May 4, 2025
9b76d3f
ST-2 add bug on purpose (again)
bitcoder May 5, 2025
fa4280d
ST-2 fix bug
bitcoder May 5, 2025
d948d4b
Merge branch 'dummy_feature' of https://github.com/bitcoder/tutorial-…
bitcoder May 5, 2025
3fa8cf5
ST-2 add bug on purpose
bitcoder May 5, 2025
75fbd3b
ST-2 dummy bug
bitcoder May 6, 2025
d8cffba
ST-2 fix dummy test
bitcoder May 6, 2025
d4a8045
bug on purpose
bitcoder Nov 6, 2025
fbb8cda
fix bug
bitcoder Nov 6, 2025
f68ed6b
Merge branch 'main' into dummy_feature
bitcoder Nov 11, 2025
b8ad762
ST-2 bug on purpose
bitcoder Nov 11, 2025
2b0c282
typo
bitcoder Nov 11, 2025
336740f
ST-2 fix bug
bitcoder Nov 11, 2025
af17bb0
ST-e add bug on purpose
bitcoder Nov 11, 2025
c2b99ad
ST-2 bug on purpose
bitcoder Nov 11, 2025
3310313
ST-2 bug on purpose
bitcoder Nov 11, 2025
25445ec
ST-2 fix bug
bitcoder Nov 11, 2025
452a32d
ST-2 bug on purpose
bitcoder Nov 11, 2025
bed8af0
ST-2 bug fix
bitcoder Nov 11, 2025
c5df45c
ST-2 bug on purpose
bitcoder Nov 12, 2025
d9295ed
ST-2 bug fix
bitcoder Nov 12, 2025
4f4625a
DEMO-1 endpoint for updating user
bitcoder Dec 3, 2025
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
16 changes: 15 additions & 1 deletion .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ jobs:
strategy:
matrix:
java: [ '17', '21' ]

permissions:
pull-requests: write

steps:
- uses: actions/checkout@v4
with:
Expand Down Expand Up @@ -60,3 +62,15 @@ jobs:
REVISON: ${{ github.ref_name}}
TEST_ENVIRONMENT: java${{ matrix.java }}
run: mvn -Dxray.clientId=${{ env.XRAYCLOUD_CLIENT_ID }} -Dxray.clientSecret=${{ env.XRAYCLOUD_CLIENT_SECRET }} -Dxray.testEnvironment=${{ env.TEST_ENVIRONMENT }} -Dxray.testPlanKey=${{ env.XRAYCLOUD_TEST_PLAN_KEY }} -Dxray.revision=${{ env.REVISON }} xray:import-results
- name: add link to Test Plan having the Test Executions (one per Java version) on the build summary
run: |
echo "| Link |" >> $GITHUB_STEP_SUMMARY
echo "| --- |" >> $GITHUB_STEP_SUMMARY
echo "| Test Plan: [${{ vars.XRAYCLOUD_TEST_PLAN_KEY }}](${{ vars.JIRACLOUD_BASE_URL }}/browse/${{ vars.XRAYCLOUD_TEST_PLAN_KEY }}) | " >> $GITHUB_STEP_SUMMARY
- name: add link to Test Plan on the PR
uses: mshick/add-pr-comment@v2
if: github.event_name == 'pull_request'
with:
message: |
Test Plan: [${{ vars.XRAYCLOUD_TEST_PLAN_KEY }}](${{ vars.JIRACLOUD_BASE_URL }}/browse/${{ vars.XRAYCLOUD_TEST_PLAN_KEY }})

Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,22 @@
public ResponseEntity<User> getCarById(@PathVariable(value = "id") Long id)
throws ResourceNotFoundException {
User user = userService.getUserDetails(id)
.orElseThrow(() -> new ResourceNotFoundException("User not found for id: " + id));

Check failure on line 36 in src/main/java/com/sergiofreire/xray/tutorials/springboot/boundary/UserRestController.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define a constant instead of duplicating this literal "User not found for id: " 3 times.

See more on https://sonarcloud.io/project/issues?id=bitcoder_tutorial-spring&issues=AZrj0w6h0l1H_DngXaGZ&open=AZrj0w6h0l1H_DngXaGZ&pullRequest=9
return ResponseEntity.ok().body(user);
}

@PutMapping("/users/{id}")
public ResponseEntity<User> updateUser(@PathVariable(value = "id") Long id, @RequestBody User userDetails)
Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing input validation. The updateUser method accepts userDetails without validating it (e.g., using @Valid annotation). This could allow invalid data (e.g., empty username, short password) to be saved, bypassing the validation constraints defined in the User entity. Consider adding @Valid before @RequestBody User userDetails to ensure validation is enforced.

Copilot uses AI. Check for mistakes.
throws ResourceNotFoundException {
User user = userService.getUserDetails(id)
.orElseThrow(() -> new ResourceNotFoundException("User not found for id: " + id));
user.setName(userDetails.getName());
user.setUsername(userDetails.getUsername());
user.setPassword(userDetails.getPassword());
Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Storing passwords in plain text is a security vulnerability. The update endpoint allows password changes without any hashing or encryption. Passwords should be hashed using a secure algorithm (e.g., bcrypt) before being stored in the database. This applies to line 47 where user.setPassword(userDetails.getPassword()) directly sets the plain text password.

Copilot uses AI. Check for mistakes.
final User updatedUser = userService.save(user);
return ResponseEntity.ok(updatedUser);
}
Comment on lines +40 to +50
Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new updateUser endpoint lacks test coverage. While there are integration tests for other endpoints (create, get, list, delete) in UserRestControllerIT.java, there is no test for the PUT endpoint to verify that user updates work correctly or handle error cases (e.g., updating a non-existent user).

Copilot uses AI. Check for mistakes.
Comment on lines +40 to +50
Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing authorization check. The updateUser endpoint allows any user to update any other user's information without verifying that the requester has the necessary permissions or is updating their own account. Consider adding authentication/authorization checks to ensure users can only update their own information or that administrators have proper privileges.

Copilot uses AI. Check for mistakes.

@GetMapping(path="/users" )
public List<User> getAllUsers() {
return userService.getAllUsers();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,20 @@ void findByIdReturnsNullWhenInvalidId() {
assertThat(fromDb).isEmpty();
}

@Test
void findByUsernameReturnsUserForValidUsername() {
User john = new User("John Doe", "johndoe", "dummypassword");
entityManager.persistAndFlush(john);

User user = userRepository.findByUsername("johndoe");
assertThat(user).isEqualTo(john);
}

@Test
void findByUsernameReturnsNullWhenInvalidUsername() {
User user = userRepository.findByUsername("missinguser");
assertThat(user).isNull();
}

@Test
void findAllReturnsAllUsers() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ void setUp() {

Mockito.when(userRepository.findById(john.getId())).thenReturn(Optional.of(john));
Mockito.when(userRepository.findByUsername(john.getUsername())).thenReturn(john);
Mockito.when(userRepository.findByUsername(john.getUsername())).thenReturn(john);
Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate mock setup detected. Line 48 already configures the mock for userRepository.findByUsername(john.getUsername()), so this line is redundant and should be removed.

Suggested change
Mockito.when(userRepository.findByUsername(john.getUsername())).thenReturn(john);

Copilot uses AI. Check for mistakes.
Mockito.when(userRepository.findAll()).thenReturn(allUsers);
Mockito.when(userRepository.findById(-99L)).thenReturn(Optional.empty());
}
Expand Down Expand Up @@ -85,21 +86,22 @@ void getUserDetailsReturnsEmptyIfNonExisting() {
}

@Test
void existsReturnsTrueIfExisting() {
boolean exists = userService.exists("johndoe");
void existsReturnsTrueForValidUsername() {
boolean userFound = userService.exists("johndoe");

Mockito.verify(userRepository, VerificationModeFactory.times(1)).findByUsername(Mockito.anyString());
assertThat(exists).isTrue();
assertThat(userFound).isTrue();
}

@Test
void existsReturnsFalseIfNonExisting() {
boolean exists = userService.exists("unknown");
void existsReturnsFalseForInvalidUsername() {
boolean userFound = userService.exists("missinguser");

Mockito.verify(userRepository, VerificationModeFactory.times(1)).findByUsername(Mockito.anyString());
assertThat(exists).isFalse();
assertThat(userFound).isFalse();
}


@Test
void getAllUsersReturnsAllExistingUsers() {
User john = new User("John Doe", "johndoe", "dummypassword");
Expand Down
Loading