diff --git a/pom.xml b/pom.xml
index d5e071f9..cf9d3292 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,96 +1,153 @@
-
-
- 4.0.0
-
- org.springframework.boot
- spring-boot-starter-parent
- 3.0.6
-
-
- com.medeiros
- SPRINGProject
- 0.0.1-SNAPSHOT
- SPRINGProject
- Demo project for Spring Boot
-
- 20
-
- 6.0.3
-
-
-
- org.springframework.boot
- spring-boot-starter-data-jpa
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
-
- org.springframework.boot
- spring-boot-devtools
- runtime
- true
-
-
- com.mysql
- mysql-connector-j
- runtime
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
-
- org.springframework.boot
- spring-boot-starter-thymeleaf
- 3.0.6
-
-
-
- org.springframework.boot
- spring-boot-starter-security
-
-
-
- io.jsonwebtoken
- jjwt-api
- 0.11.5
-
-
-
-
-
-
- org.springframework.security
- spring-security-core
- 6.0.3
-
-
-
-
-
-
- io.jsonwebtoken
- jjwt-impl
- 0.11.5
- runtime
-
-
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
-
-
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.0.6
+
+
+
+ com.medeiros
+ SPRINGProject
+ 0.0.1-SNAPSHOT
+ SPRINGProject
+ Demo project for Spring Boot
+
+ 20
+
+ 6.0.3
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+ true
+
+
+ com.mysql
+ mysql-connector-j
+ runtime
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+ 3.0.6
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+ io.jsonwebtoken
+ jjwt-api
+ 0.11.5
+
+
+
+ org.springframework.security
+ spring-security-core
+ 6.0.3
+
+
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ 0.11.5
+ runtime
+
+
+ org.mockito
+ mockito-junit-jupiter
+ 2.23.4
+ test
+
+
+
+ io.spring.javaformat
+ spring-javaformat-formatter
+ 0.0.40
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.8.11
+
+
+
+ prepare-agent
+
+
+
+ report
+ test
+
+ report
+
+
+ coverageReport
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.2.5
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-report-plugin
+ 3.2.5
+
+ testReport
+
+
+
+
+ org.apache.maven.plugins
+ maven-site-plugin
+ 2.1
+
+ testReport
+
+
+
+
+ io.spring.javaformat
+ spring-javaformat-maven-plugin
+ 0.0.40
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/java/com/medeiros/SPRINGProject/Controllers/MusicControllerCreateMusicTest.java b/src/test/java/com/medeiros/SPRINGProject/Controllers/MusicControllerCreateMusicTest.java
new file mode 100644
index 00000000..d04610f0
--- /dev/null
+++ b/src/test/java/com/medeiros/SPRINGProject/Controllers/MusicControllerCreateMusicTest.java
@@ -0,0 +1,654 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test maven-music-github using AI Type Azure Open AI and AI Model gpt-5
+
+ROOST_METHOD_HASH=createMusic_9c5dad48b0
+ROOST_METHOD_SIG_HASH=createMusic_4606fc0d94
+
+Scenario 1: Successful creation with fully populated, valid inputs
+
+Details:
+ TestName: returnsSuccessMessageAndPersistsWhenInputsAreValid
+ Description: Verifies that when valid strings are supplied for MusicDescription, MusicName, and Music and a valid positive integer is supplied for Userid, the controller creates a MusicModel, calls MusicRepository.save once, and returns the success message.
+
+Execution:
+ Arrange: Create a MusicController with a mocked MusicRepository injected. Prepare non-empty strings for MusicDescription, MusicName, and Music, and a positive integer for Userid.
+ Act: Invoke createMusic with the arranged values.
+ Assert: Use JUnit assertions to confirm that the returned String equals "Operação Feita" and verify via the mock that MusicRepo.save was invoked exactly once with a non-null MusicModel instance.
+
+Validation:
+ Confirms the primary happy-path behavior of the method: it constructs a model and persists it through MusicRepository, returning the fixed success message. This validates correct repository interaction and response generation for nominal inputs.
+
+Scenario 2: Exact return message including diacritics
+
+Details:
+ TestName: returnsExactPortugueseSuccessMessage
+ Description: Ensures the returned message is exactly "Operação Feita" including diacritics and spacing, preventing accidental changes to user-facing text.
+
+Execution:
+ Arrange: Instantiate MusicController with a mocked MusicRepository; set valid non-empty inputs and a valid Userid.
+ Act: Invoke createMusic with the arranged values.
+ Assert: Use JUnit to assert that the returned string is exactly "Operação Feita" (same characters, same case, same accents).
+
+Validation:
+ Guards against regressions in localized messages, ensuring clients depending on the exact phrase continue to work as expected.
+
+Scenario 3: Repository save is invoked once per call
+
+Details:
+ TestName: callsRepositorySaveExactlyOnce
+ Description: Checks that MusicRepo.save is invoked exactly one time for a single createMusic invocation.
+
+Execution:
+ Arrange: Create a MusicController with a mocked MusicRepository injected; prepare valid inputs.
+ Act: Call createMusic once with the valid inputs.
+ Assert: Verify through the mock that MusicRepo.save was called exactly once; no other unexpected repository calls are performed.
+
+Validation:
+ Ensures no duplicate persistence attempts occur, which could create duplicate data or introduce performance issues.
+
+Scenario 4: Empty MusicDescription is accepted and persisted
+
+Details:
+ TestName: allowsEmptyMusicDescription
+ Description: Validates behavior when MusicDescription is an empty string; the method should still construct a MusicModel, pass it to MusicRepo.save, and return the success message.
+
+Execution:
+ Arrange: Mock MusicRepository; set MusicDescription to "", while MusicName and Music are non-empty; choose a valid Userid.
+ Act: Call createMusic with MusicDescription as empty string.
+ Assert: Assert return equals "Operação Feita" and verify MusicRepo.save was invoked.
+
+Validation:
+ Confirms that the controller itself does not enforce description presence and delegates any validation to downstream layers.
+
+Scenario 5: Empty MusicName is accepted and persisted
+
+Details:
+ TestName: allowsEmptyMusicName
+ Description: Confirms that an empty MusicName does not prevent saving and success response.
+
+Execution:
+ Arrange: Mock MusicRepository; set MusicName to ""; ensure MusicDescription and Music are non-empty; valid Userid.
+ Act: Invoke createMusic.
+ Assert: Assert returned string equals "Operação Feita"; verify save called.
+
+Validation:
+ Demonstrates the controller performs no name validation and persists as-is.
+
+Scenario 6: Empty Music content is accepted and persisted
+
+Details:
+ TestName: allowsEmptyMusicContent
+ Description: Confirms that an empty Music string does not block saving and the success message is returned.
+
+Execution:
+ Arrange: Mock MusicRepository; set Music to ""; set other fields non-empty; valid Userid.
+ Act: Call createMusic.
+ Assert: Confirm the return value is "Operação Feita" and verify save was called.
+
+Validation:
+ Ensures the method does not enforce content presence at the controller layer.
+
+Scenario 7: All input strings empty still persist
+
+Details:
+ TestName: persistsWhenAllStringsAreEmpty
+ Description: Verifies behavior when MusicDescription, MusicName, and Music are all empty strings.
+
+Execution:
+ Arrange: Mock MusicRepository; set all three parameters to ""; valid Userid.
+ Act: Invoke createMusic.
+ Assert: Assert return is "Operação Feita" and verify save invocation.
+
+Validation:
+ Demonstrates that the controller layer does not perform input validation and will attempt to persist even minimal inputs.
+
+Scenario 8: Null inputs when directly invoking the method
+
+Details:
+ TestName: handlesNullStringsWhenDirectlyInvoked
+ Description: When calling the method directly (bypassing Spring MVC binding) with null values for MusicDescription, MusicName, or Music, confirm expected behavior. Since the method does not validate, it will attempt to construct MusicModel and save it; if the constructor accepts nulls, saving proceeds; otherwise, an exception may be thrown.
+
+Execution:
+ Arrange: Inject a mocked MusicRepository; prepare one or more nulls among MusicDescription, MusicName, and Music; valid Userid.
+ Act: Invoke createMusic with null parameters.
+ Assert: Use JUnit to either (a) assert that the method returns "Operação Feita" and save is called (if no exception occurs) or (b) expect an exception (e.g., NullPointerException or IllegalArgumentException) and verify save is not called.
+
+Validation:
+ Documents behavior for direct method invocation with nulls, clarifying that any null-safety enforcement would stem from MusicModel or downstream layers, not this controller method.
+
+Scenario 9: Negative Userid is accepted and persisted
+
+Details:
+ TestName: acceptsNegativeUserid
+ Description: Ensures that a negative Userid does not prevent saving and returning the success message.
+
+Execution:
+ Arrange: Mock MusicRepository; set Userid to a negative integer; provide non-empty strings for other parameters.
+ Act: Invoke createMusic.
+ Assert: Assert return equals "Operação Feita" and verify save was called.
+
+Validation:
+ Confirms the controller does not validate Userid sign and persists as-is.
+
+Scenario 10: Zero Userid is accepted and persisted
+
+Details:
+ TestName: acceptsZeroUserid
+ Description: Ensures that a Userid of 0 does not block the operation.
+
+Execution:
+ Arrange: Mock MusicRepository; set Userid = 0; valid non-empty strings for other parameters.
+ Act: Invoke createMusic.
+ Assert: Assert return is "Operação Feita"; verify save called.
+
+Validation:
+ Shows that the controller does not enforce minimum Userid constraints.
+
+Scenario 11: Large integer Userid (Integer.MAX_VALUE) is accepted
+
+Details:
+ TestName: acceptsMaxIntUserid
+ Description: Validates that very large Userid values are passed through and saved.
+
+Execution:
+ Arrange: Mock MusicRepository; set Userid to Integer.MAX_VALUE; use valid strings.
+ Act: Invoke createMusic.
+ Assert: Confirm return equals "Operação Feita" and verify save was invoked.
+
+Validation:
+ Demonstrates boundary handling for numeric path variables at the controller level.
+
+Scenario 12: Repository throws an unchecked exception during save
+
+Details:
+ TestName: propagatesExceptionWhenRepositorySaveFails
+ Description: Ensures that if MusicRepo.save throws a runtime exception, the controller method does not swallow it and the exception propagates to the caller.
+
+Execution:
+ Arrange: Mock MusicRepository to throw a RuntimeException when save is called; provide valid parameters.
+ Act: Invoke createMusic and expect the exception.
+ Assert: Use JUnit’s expected exception mechanisms or assertions to confirm the exception is thrown; verify no success message is returned.
+
+Validation:
+ Confirms the absence of exception handling in the method, which is important for observability and upstream error handling policies.
+
+Scenario 13: No interactions with LogRepository or Date field
+
+Details:
+ TestName: doesNotInteractWithLogRepositoryOrDate
+ Description: Confirms that createMusic does not use the LogRepository Log field nor the Date field during execution.
+
+Execution:
+ Arrange: Inject mocks for MusicRepository and LogRepository into the controller; provide valid parameters.
+ Act: Invoke createMusic.
+ Assert: Verify MusicRepo.save was called once; verify that the LogRepository mock had zero interactions and the Date field was not modified or referenced (no methods invoked on LogRepository).
+
+Validation:
+ Ensures separation of concerns and that logging behavior is not unexpectedly triggered by music creation.
+
+Scenario 14: Controller method mapping works via HTTP (MockMvc)
+
+Details:
+ TestName: httpPostBindsParametersAndReturnsSuccess
+ Description: Using a Spring MVC testing setup, verifies that POST /music/create/{Userid} with the required request parameters (MusicDescription, MusicName, Music) routes to the controller, calls MusicRepo.save, and returns the success message in the response body.
+
+Execution:
+ Arrange: Build a test slice with MusicController wired and a mocked MusicRepository; configure MockMvc. Prepare a POST request to /music/create/123 with form parameters MusicDescription, MusicName, and Music.
+ Act: Perform the MockMvc POST.
+ Assert: Assert HTTP 200 status and response body equals "Operação Feita"; verify MusicRepo.save called once.
+
+Validation:
+ Confirms correct request mapping, parameter binding, and end-to-end behavior at the controller layer.
+
+Scenario 15: Missing required request parameter yields HTTP 400 (MVC layer)
+
+Details:
+ TestName: missingRequestParamYieldsBadRequest
+ Description: Validates that omitting a required request parameter (e.g., MusicName) from the POST request results in a 400 Bad Request and that the repository is not invoked.
+
+Execution:
+ Arrange: Configure MockMvc with MusicController and a mocked MusicRepository. Prepare a POST to /music/create/{Userid} without the MusicName parameter.
+ Act: Execute the request.
+ Assert: Assert HTTP status 400; verify MusicRepo.save was never called.
+
+Validation:
+ Ensures Spring’s parameter binding enforces required parameters and prevents incomplete requests from reaching persistence.
+
+Scenario 16: Non-integer Userid in the path yields HTTP 400 (MVC layer)
+
+Details:
+ TestName: nonNumericUseridPathVariableYieldsBadRequest
+ Description: Confirms that supplying a non-integer path variable for Userid (e.g., "abc") causes the framework to return 400 Bad Request and the repository is not called.
+
+Execution:
+ Arrange: Configure MockMvc; create a POST to /music/create/abc with valid request parameters.
+ Act: Perform the request.
+ Assert: Assert HTTP 400; verify no interactions with MusicRepo.save.
+
+Validation:
+ Verifies Spring MVC’s type conversion and error handling for path variables.
+
+Scenario 17: Inputs with Unicode characters are accepted
+
+Details:
+ TestName: acceptsUnicodeInInputs
+ Description: Ensures that MusicDescription, MusicName, and Music can contain Unicode characters (e.g., accented letters, emojis) and still persist successfully with the success message returned.
+
+Execution:
+ Arrange: Mock MusicRepository; prepare strings with Unicode content; valid Userid.
+ Act: Invoke createMusic.
+ Assert: Assert return equals "Operação Feita"; verify save called once.
+
+Validation:
+ Confirms the controller handles internationalized content and does not perform restrictive character filtering.
+
+Scenario 18: Inputs with leading/trailing whitespace are passed through
+
+Details:
+ TestName: preservesWhitespaceInInputs
+ Description: Verifies that the controller does not trim or alter leading/trailing whitespace in inputs before persistence (pass-through behavior).
+
+Execution:
+ Arrange: Mock MusicRepository; supply MusicDescription, MusicName, and Music with leading/trailing spaces; valid Userid.
+ Act: Invoke createMusic.
+ Assert: Assert returned string equals "Operação Feita"; verify save called once. (Optionally, capture the argument and confirm the object was created and passed as-is without alteration, without relying on unspecified getters.)
+
+Validation:
+ Demonstrates that input normalization is not performed at this layer and any such logic should be implemented elsewhere if required.
+
+Scenario 19: Multiple consecutive calls persist each request
+
+Details:
+ TestName: multipleInvocationsCallSaveForEachRequest
+ Description: Ensures that calling createMusic multiple times results in a corresponding number of save invocations and success messages for each call.
+
+Execution:
+ Arrange: Mock MusicRepository; prepare valid inputs; plan to call the method N times (e.g., 3).
+ Act: Invoke createMusic repeatedly with the inputs (possibly varying inputs per call).
+ Assert: Assert each call returns "Operação Feita"; verify MusicRepo.save was called exactly N times.
+
+Validation:
+ Confirms consistent behavior across multiple invocations and absence of hidden state or caching that could suppress saves.
+
+Scenario 20: Null-injected MusicRepository causes a failure
+
+Details:
+ TestName: nullRepositoryInjectionCausesNullPointerException
+ Description: If MusicRepo is not injected (left null), the method should throw a NullPointerException upon attempting to call save.
+
+Execution:
+ Arrange: Create a MusicController instance without injecting MusicRepository (or explicitly set MusicRepo to null in the test setup); provide valid inputs.
+ Act: Invoke createMusic.
+ Assert: Assert that a NullPointerException (or similar) is thrown and that no return value is produced.
+
+Validation:
+ Highlights the importance of dependency injection for correct operation and helps detect misconfiguration in wiring.
+
+Scenario 21: Verify no side effects beyond saving and returning message
+
+Details:
+ TestName: noAdditionalSideEffectsBeyondSaveAndReturn
+ Description: Confirms that the method performs only two actions: constructing a MusicModel and calling MusicRepo.save, followed by returning the message, with no other repository or logging interactions.
+
+Execution:
+ Arrange: Mock MusicRepository and LogRepository; supply valid inputs.
+ Act: Invoke createMusic.
+ Assert: Verify MusicRepo.save was called once; verify there were no further interactions with MusicRepo; verify zero interactions with LogRepository; assert returned message equals "Operação Feita".
+
+Validation:
+ Ensures minimal and predictable side effects, aiding maintainability and testability.
+
+Scenario 22: Validate parameter name bindings through direct invocation
+
+Details:
+ TestName: directInvocationUsesProvidedParameters
+ Description: When the method is called directly in unit tests (bypassing MVC), confirm that the provided parameter values are used to construct and save a MusicModel, and that the success message is returned.
+
+Execution:
+ Arrange: Mock MusicRepository and inject it into the controller; choose distinctive values for MusicDescription, MusicName, Music, and a specific Userid.
+ Act: Directly call createMusic with those exact values.
+ Assert: Assert return equals "Operação Feita" and verify MusicRepo.save received a MusicModel instance (without assuming unavailable getters/setters).
+
+Validation:
+ Demonstrates that annotations are not required for correctness during direct invocation and that the method uses the provided arguments as-is.
+
+Scenario 23: Very long string inputs are accepted (boundaries)
+
+Details:
+ TestName: acceptsVeryLongStrings
+ Description: Verifies that very long strings for MusicDescription, MusicName, and Music do not cause the controller method to fail (subject to any downstream limits not enforced here).
+
+Execution:
+ Arrange: Mock MusicRepository; construct long strings (e.g., tens of thousands of characters); valid Userid.
+ Act: Invoke createMusic.
+ Assert: Assert return equals "Operação Feita"; verify save called once.
+
+Validation:
+ Confirms the controller imposes no intrinsic length restrictions and defers any validation to underlying layers.
+
+Scenario 24: Whitespace-only inputs are accepted
+
+Details:
+ TestName: acceptsWhitespaceOnlyStrings
+ Description: Verifies that strings containing only whitespace are accepted and persisted without validation at the controller level.
+
+Execution:
+ Arrange: Mock MusicRepository; set MusicDescription, MusicName, and Music to whitespace-only strings; valid Userid.
+ Act: Invoke createMusic.
+ Assert: Assert the returned message is "Operação Feita"; verify save called once.
+
+Validation:
+ Documents pass-through behavior for inputs that are non-null but semantically empty, valuable for downstream validation planning.
+
+*/
+
+// ********RoostGPT********
+
+package com.medeiros.SPRINGProject.Controllers;
+
+import com.medeiros.SPRINGProject.Models.MusicModel;
+import com.medeiros.SPRINGProject.Models.MusicRepository;
+import com.medeiros.SPRINGProject.Models.LogRepository;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import org.junit.jupiter.api.*;
+import com.medeiros.SPRINGProject.Models.LogModel;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@ExtendWith(MockitoExtension.class)
+public class MusicControllerCreateMusicTest {
+
+ @Mock
+ private MusicRepository musicRepository;
+
+ @Mock
+ private LogRepository logRepository;
+
+ @InjectMocks
+ private MusicController controller;
+
+ @InjectMocks
+ private HttpMusicController httpController;
+
+ private MockMvc mockMvc;
+
+ @BeforeEach
+ public void setUp() {
+ reset(musicRepository, logRepository);
+ mockMvc = MockMvcBuilders.standaloneSetup(httpController).build();
+ }
+
+ @RestController
+ static class HttpMusicController extends MusicController {
+
+ @PostMapping("/music/create/{Userid}")
+ public String createMusic(@RequestParam(name = "MusicDescription") String MusicDescription,
+ @RequestParam(name = "MusicName") String MusicName, @RequestParam(name = "Music") String Music,
+ @PathVariable int Userid) {
+ return super.createMusic(MusicDescription, MusicName, Music, Userid);
+ }
+
+ }
+
+ @Test
+ @Tag("valid")
+ public void testReturnsSuccessMessageAndPersistsWhenInputsAreValid() {
+ String musicDescription = "A calm piano piece";
+ String musicName = "Nocturne";
+ String music = "C E G";
+ int userId = 42;
+ String result = controller.createMusic(musicDescription, musicName, music, userId);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) result);
+ ArgumentCaptor captor = ArgumentCaptor.forClass(MusicModel.class);
+ verify(musicRepository, times(1)).save(captor.capture());
+ MusicModel saved = captor.getValue();
+ assertNotNull((Object) saved);
+ }
+
+ @Test
+ @Tag("valid")
+ public void testReturnsExactPortugueseSuccessMessage() {
+ String res = controller.createMusic("desc", "name", "content", 10);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) res);
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("valid")
+ public void testCallsRepositorySaveExactlyOnce() {
+ String res = controller.createMusic("desc", "name", "content", 5);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) res);
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("valid")
+ public void testAllowsEmptyMusicDescription() {
+ String result = controller.createMusic("", "Track", "data", 1);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) result);
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("valid")
+ public void testAllowsEmptyMusicName() {
+ String result = controller.createMusic("Some desc", "", "data", 2);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) result);
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("valid")
+ public void testAllowsEmptyMusicContent() {
+ String result = controller.createMusic("Some desc", "Name", "", 3);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) result);
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("valid")
+ public void testPersistsWhenAllStringsAreEmpty() {
+ String result = controller.createMusic("", "", "", 7);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) result);
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("valid")
+ public void testHandlesNullStringsWhenDirectlyInvoked() {
+ String result = controller.createMusic(null, null, null, 8);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) result);
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("boundary")
+ public void testAcceptsNegativeUserid() {
+ String result = controller.createMusic("desc", "name", "content", -5);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) result);
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("boundary")
+ public void testAcceptsZeroUserid() {
+ String result = controller.createMusic("desc", "name", "content", 0);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) result);
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("boundary")
+ public void testAcceptsMaxIntUserid() {
+ String result = controller.createMusic("desc", "name", "content", Integer.MAX_VALUE);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) result);
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("invalid")
+ public void testPropagatesExceptionWhenRepositorySaveFails() {
+ doThrow(new RuntimeException("save failed")).when(musicRepository).save(any(MusicModel.class));
+ assertThrows(RuntimeException.class, () -> controller.createMusic("desc", "name", "content", 11));
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("valid")
+ public void testDoesNotInteractWithLogRepositoryOrDate() {
+ String result = controller.createMusic("desc", "name", "content", 12);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) result);
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ verifyNoInteractions(logRepository);
+ }
+
+ @Test
+ @Tag("integration")
+ public void testHttpPostBindsParametersAndReturnsSuccess() throws Exception {
+ mockMvc
+ .perform(post("/music/create/{Userid}", 123).param("MusicDescription", "desc")
+ .param("MusicName", "name")
+ .param("Music", "content"))
+ .andExpect(status().isOk())
+ .andExpect(content().string("Operação Feita"));
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("integration")
+ public void testMissingRequestParamYieldsBadRequest() throws Exception {
+ mockMvc.perform(post("/music/create/{Userid}", 123).param("MusicDescription", "desc")
+ // missing MusicName
+ .param("Music", "content")).andExpect(status().isBadRequest());
+ verifyNoInteractions(musicRepository);
+ }
+
+ @Test
+ @Tag("integration")
+ public void testNonNumericUseridPathVariableYieldsBadRequest() throws Exception {
+ mockMvc
+ .perform(post("/music/create/abc").param("MusicDescription", "desc")
+ .param("MusicName", "name")
+ .param("Music", "content"))
+ .andExpect(status().isBadRequest());
+ verifyNoInteractions(musicRepository);
+ }
+
+ @Test
+ @Tag("valid")
+ public void testAcceptsUnicodeInInputs() {
+ String result = controller.createMusic("Descrição 🎶", "Canção Árvore", "♪♫🎵", 15);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) result);
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("valid")
+ public void testPreservesWhitespaceInInputs() {
+ String result = controller.createMusic(" desc ", " name ", " content ", 16);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) result);
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("valid")
+ public void testMultipleInvocationsCallSaveForEachRequest() {
+ int timesToInvoke = 3; // TODO adjust number of repetitions if needed
+ for (int i = 0; i < timesToInvoke; i++) {
+ String res = controller.createMusic("d" + i, "n" + i, "c" + i, i);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) res);
+ }
+ verify(musicRepository, times(timesToInvoke)).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("invalid")
+ public void testNullRepositoryInjectionCausesNullPointerException() {
+ MusicController misconfigured = new MusicController();
+ assertThrows(NullPointerException.class, () -> misconfigured.createMusic("desc", "name", "content", 20));
+ }
+
+ @Test
+ @Tag("valid")
+ public void testNoAdditionalSideEffectsBeyondSaveAndReturn() {
+ String res = controller.createMusic("desc", "name", "content", 21);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) res);
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ verifyNoMoreInteractions(musicRepository);
+ verifyNoInteractions(logRepository);
+ }
+
+ @Test
+ @Tag("valid")
+ public void testDirectInvocationUsesProvidedParameters() {
+ String response = controller.createMusic("distinct-desc", "distinct-name", "distinct-content", 22);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) response);
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("boundary")
+ public void testAcceptsVeryLongStrings() {
+ String longStr = "a".repeat(10000);
+ String response = controller.createMusic(longStr, longStr, longStr, 23);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) response);
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("boundary")
+ public void testAcceptsWhitespaceOnlyStrings() {
+ String whitespace = " ";
+ String response = controller.createMusic(whitespace, whitespace, whitespace, 24);
+ String expected = "Operação Feita";
+ assertEquals((String) expected, (String) response);
+ verify(musicRepository, times(1)).save(any(MusicModel.class));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/medeiros/SPRINGProject/Controllers/MusicControllerDeleteMusicTest.java b/src/test/java/com/medeiros/SPRINGProject/Controllers/MusicControllerDeleteMusicTest.java
new file mode 100644
index 00000000..fb2cba06
--- /dev/null
+++ b/src/test/java/com/medeiros/SPRINGProject/Controllers/MusicControllerDeleteMusicTest.java
@@ -0,0 +1,100 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test maven-music-github using AI Type Azure Open AI and AI Model gpt-5
+
+ROOST_METHOD_HASH=deleteMusic_e3b3d353e4
+ROOST_METHOD_SIG_HASH=deleteMusic_3c6d20ad7a
+
+Scenario 1: Successful deletion returns the expected confirmation string
+
+Details:
+ TestName: deleteMusicReturnsDeletadoOnValidId
+ Description: Verify that calling MusicController.deleteMusic with a typical valid integer id returns the string "Deletado", indicating a successful deletion operation.
+
+Execution:
+ Arrange: Set up a MusicController with a mocked MusicRepository. Ensure the mock is configured to accept deleteById for a valid id without throwing any exception.
+ Act: Invoke deleteMusic with a valid id (e.g., 42).
+ Assert: Use JUnit assertions to confirm that the returned value is exactly "Deletado".
+
+Validation:
+ Confirm that the controller’s method returns the fixed success message expected by consumers. This validates the method’s contract about response content and signals correct flow when the repository deletion succeeds.
+
+*/
+
+// ********RoostGPT********
+
+package com.medeiros.SPRINGProject.Controllers;
+
+import com.medeiros.SPRINGProject.Models.LogRepository;
+import com.medeiros.SPRINGProject.Models.MusicRepository;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import org.junit.jupiter.api.*;
+import com.medeiros.SPRINGProject.Models.LogModel;
+import com.medeiros.SPRINGProject.Models.MusicModel;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@ExtendWith(MockitoExtension.class)
+public class MusicControllerDeleteMusicTest {
+
+ @Mock
+ private MusicRepository MusicRepo;
+
+ @Mock
+ private LogRepository Log;
+
+ @InjectMocks
+ private MusicController controller;
+
+ @Test
+ @Tag("valid")
+ public void testDeleteMusicReturnsDeletadoOnValidId() {
+ int validId = (int) 42;
+ doNothing().when(MusicRepo).deleteById(validId);
+ String actual = (String) controller.deleteMusic(validId);
+ assertEquals((String) "Deletado", (String) actual);
+ verify(MusicRepo, times(1)).deleteById(validId);
+ }
+
+ @Test
+ @Tag("invalid")
+ public void testDeleteMusicPropagatesExceptionFromRepository() {
+ int anyId = (int) 7; // TODO change the id if needed for specific scenarios
+ Mockito.doThrow(new RuntimeException("delete error")).when(MusicRepo).deleteById(anyId);
+ assertThrows(RuntimeException.class, () -> controller.deleteMusic(anyId));
+ verify(MusicRepo, times(1)).deleteById(anyId);
+ }
+
+ @Test
+ @Tag("invalid")
+ public void testDeleteMusicWithNegativeIdReturnsDeletadoWhenRepoDoesNotThrow() {
+ int negativeId = (int) -1;
+ doNothing().when(MusicRepo).deleteById(negativeId);
+ String actual = (String) controller.deleteMusic(negativeId);
+ assertEquals((String) "Deletado", (String) actual);
+ verify(MusicRepo, times(1)).deleteById(negativeId);
+ }
+
+ @Test
+ @Tag("boundary")
+ public void testDeleteMusicWithMaxIntIdReturnsDeletado() {
+ int boundaryId = (int) Integer.MAX_VALUE;
+ doNothing().when(MusicRepo).deleteById(boundaryId);
+ String actual = (String) controller.deleteMusic(boundaryId);
+ assertEquals((String) "Deletado", (String) actual);
+ verify(MusicRepo, times(1)).deleteById(boundaryId);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/medeiros/SPRINGProject/Controllers/MusicControllerFindMusicByTest.java b/src/test/java/com/medeiros/SPRINGProject/Controllers/MusicControllerFindMusicByTest.java
new file mode 100644
index 00000000..acce9750
--- /dev/null
+++ b/src/test/java/com/medeiros/SPRINGProject/Controllers/MusicControllerFindMusicByTest.java
@@ -0,0 +1,114 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test maven-music-github using AI Type Azure Open AI and AI Model gpt-5
+
+ROOST_METHOD_HASH=findMusicBy_5035b89150
+ROOST_METHOD_SIG_HASH=findMusicBy_179b3d7d86
+
+Scenario 1: Return an existing MusicModel when the repository finds a match
+
+Details:
+ TestName: returnsExistingMusicModelWhenIdExists
+ Description: Verifies that findMusicBy returns the same MusicModel instance that MusicRepository.findById provides when a record exists for the given id.
+
+Execution:
+ Arrange: Create a MusicController with injected mocks. Configure MusicRepository.findById(42) to return a non-null MusicModel instance (e.g., a stubbed object created for the test).
+ Act: Invoke findMusicBy(42).
+ Assert: Use assertSame to confirm that the returned MusicModel is exactly the same instance returned by MusicRepository.findById. Additionally, verify that MusicRepository.findById was invoked exactly once with id 42.
+
+Validation:
+ Confirms correct delegation from the controller to the repository and ensures no transformation or wrapping occurs. This is significant to guarantee that controller behavior is a simple pass-through, preserving repository results as-is.
+
+*/
+
+// ********RoostGPT********
+
+package com.medeiros.SPRINGProject.Controllers;
+
+import com.medeiros.SPRINGProject.Models.LogRepository;
+import com.medeiros.SPRINGProject.Models.MusicModel;
+import com.medeiros.SPRINGProject.Models.MusicRepository;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import org.junit.jupiter.api.*;
+import com.medeiros.SPRINGProject.Models.LogModel;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@ExtendWith(MockitoExtension.class)
+public class MusicControllerFindMusicByTest {
+
+ @Mock
+ private MusicRepository MusicRepo;
+
+ @Mock
+ private LogRepository Log;
+
+ @InjectMocks
+ private MusicController controller;
+
+ @Test
+ @Tag("valid")
+ public void testReturnsExistingMusicModelWhenIdExists() {
+ int id = 42; // TODO: Adjust if repository data setup changes
+ MusicModel expected = new MusicModel(100, "SongName", "SongContent", "SongDescription");
+ when(MusicRepo.findById(id)).thenReturn(expected);
+ MusicModel actual = controller.findMusicBy(id);
+ assertSame((Object) expected, (Object) actual,
+ "Controller should return the same MusicModel instance from repository");
+ verify(MusicRepo, times(1)).findById(id);
+ }
+
+ @Test
+ @Tag("invalid")
+ public void testReturnsNullWhenIdDoesNotExist() {
+ int missingId = 999; // TODO: Adjust if repository mock setup requires different
+ // id
+ when(MusicRepo.findById(missingId)).thenReturn(null);
+ MusicModel actual = controller.findMusicBy(missingId);
+ assertNull((Object) actual, "Controller should return null when repository returns null");
+ verify(MusicRepo, times(1)).findById(missingId);
+ }
+
+ @Test
+ @Tag("boundary")
+ public void testDelegatesCallForBoundaryIdZero() {
+ int boundaryId = 0;
+ MusicModel expected = new MusicModel(1, "BoundarySong", "BoundaryContent", "BoundaryDescription");
+ when(MusicRepo.findById(boundaryId)).thenReturn(expected);
+ MusicModel actual = controller.findMusicBy(boundaryId);
+ assertSame((Object) expected, (Object) actual,
+ "Controller should delegate and return the same instance for boundary id");
+ verify(MusicRepo, times(1)).findById(boundaryId);
+ }
+
+ @Test
+ @Tag("invalid")
+ public void testPropagatesExceptionFromRepository() {
+ int problematicId = -1;
+ RuntimeException repoException = new RuntimeException("Repository failure"); // TODO:
+ // Adjust
+ // message
+ // if
+ // needed
+ // for
+ // specific
+ // assertions
+ when(MusicRepo.findById(problematicId)).thenThrow(repoException);
+ assertThrows((Class extends Throwable>) RuntimeException.class, () -> controller.findMusicBy(problematicId),
+ "Controller should propagate repository exceptions");
+ verify(MusicRepo, times(1)).findById(problematicId);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/medeiros/SPRINGProject/Controllers/MusicControllerUpdateMusicByIdTest.java b/src/test/java/com/medeiros/SPRINGProject/Controllers/MusicControllerUpdateMusicByIdTest.java
new file mode 100644
index 00000000..382e7d10
--- /dev/null
+++ b/src/test/java/com/medeiros/SPRINGProject/Controllers/MusicControllerUpdateMusicByIdTest.java
@@ -0,0 +1,136 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test maven-music-github using AI Type Azure Open AI and AI Model gpt-5
+
+ROOST_METHOD_HASH=updateMusicById_aa137517f5
+ROOST_METHOD_SIG_HASH=updateMusicById_857ee29aaf
+
+Scenario 1: Successfully update an existing music record and return confirmation
+
+Details:
+ TestName: updateExistingMusicUpdatesAllFieldsAndReturnsConfirmation
+ Description: Verifies that when a valid id is provided and the record exists, the method updates MusicName, MusicDescription, and Music fields on the retrieved MusicModel, saves it via MusicRepository, and returns the confirmation message "Música Alterada!".
+
+Execution:
+ Arrange: Prepare a MusicController with a mocked MusicRepository. Stub MusicRepository.findById(id) to return a non-null MusicModel instance suitable for updating.
+ Act: Invoke updateMusicById with a valid id and non-empty values for MusicName, MusicDescription, and Music.
+ Assert: Use assertEquals to verify the returned string equals "Música Alterada!". Verify that MusicModel.setMusic, MusicModel.setMusicDescription, and MusicModel.setMusicName are each called once with the provided arguments. Verify that MusicRepository.save is called once with the same MusicModel instance returned by findById.
+
+Validation:
+ Confirms the primary functionality of the update endpoint: retrieving, mutating, persisting the entity, and returning the expected confirmation message. Demonstrates correct interaction with the repository and data mutation on the model.
+
+*/
+
+// ********RoostGPT********
+
+package com.medeiros.SPRINGProject.Controllers;
+
+import com.medeiros.SPRINGProject.Models.LogModel;
+import com.medeiros.SPRINGProject.Models.LogRepository;
+import com.medeiros.SPRINGProject.Models.MusicModel;
+import com.medeiros.SPRINGProject.Models.MusicRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.same;
+import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.*;
+import org.springframework.web.bind.annotation.*;
+
+@ExtendWith(MockitoExtension.class)
+public class MusicControllerUpdateMusicByIdTest {
+
+ @Mock
+ private MusicRepository MusicRepo;
+
+ @InjectMocks
+ private MusicController controller;
+
+ @Test
+ @Tag("valid")
+ public void testUpdateExistingMusicUpdatesAllFieldsAndReturnsConfirmation() {
+ // Leverage specified imports to keep them utilized and compilation-friendly
+ Class requestParamClass = RequestParam.class;
+ Class pathVariableClass = PathVariable.class;
+ Class autowiredClass = Autowired.class;
+ // Using provided model classes per instructions
+ LogModel dummyLogModel = new LogModel();
+ int id = 123; // TODO adjust test id if needed
+ String newName = "UpdatedName";
+ String newDesc = "UpdatedDescription";
+ String newMusic = "UpdatedMusic";
+ MusicModel musicToUpdate = mock(MusicModel.class);
+ when(MusicRepo.findById(id)).thenReturn(musicToUpdate);
+ String result = controller.updateMusicById(id, newName, newDesc, newMusic);
+ assertEquals((String) "Música Alterada!", (String) result);
+ verify(MusicRepo, times(1)).findById(id);
+ verify(musicToUpdate, times(1)).setMusic((String) newMusic);
+ verify(musicToUpdate, times(1)).setMusicDescription((String) newDesc);
+ verify(musicToUpdate, times(1)).setMusicName((String) newName);
+ verify(MusicRepo, times(1)).save(same(musicToUpdate));
+ verifyNoMoreInteractions(MusicRepo);
+ }
+
+ @Test
+ @Tag("invalid")
+ public void testUpdateMusicThrowsWhenRecordNotFound() {
+ int missingId = 999; // TODO adjust test id if needed
+ String anyName = "Name";
+ String anyDesc = "Description";
+ String anyMusic = "MusicContent";
+ when(MusicRepo.findById(missingId)).thenReturn(null);
+ assertThrows(NullPointerException.class,
+ () -> controller.updateMusicById(missingId, anyName, anyDesc, anyMusic));
+ verify(MusicRepo, times(1)).findById(missingId);
+ verify(MusicRepo, never()).save(any(MusicModel.class));
+ }
+
+ @Test
+ @Tag("boundary")
+ public void testUpdateWithEmptyStringsUpdatesAndSaves() {
+ int id = 456; // TODO adjust test id if needed
+ String emptyName = "";
+ String emptyDesc = "";
+ String emptyMusic = "";
+ MusicModel musicToUpdate = mock(MusicModel.class);
+ when(MusicRepo.findById(id)).thenReturn(musicToUpdate);
+ String result = controller.updateMusicById(id, emptyName, emptyDesc, emptyMusic);
+ assertEquals((String) "Música Alterada!", (String) result);
+ verify(MusicRepo, times(1)).findById(id);
+ verify(musicToUpdate, times(1)).setMusic((String) emptyMusic);
+ verify(musicToUpdate, times(1)).setMusicDescription((String) emptyDesc);
+ verify(musicToUpdate, times(1)).setMusicName((String) emptyName);
+ verify(MusicRepo, times(1)).save(same(musicToUpdate));
+ verifyNoMoreInteractions(MusicRepo);
+ }
+
+ @Test
+ @Tag("boundary")
+ public void testUpdateWithNegativeIdStillUpdatesWhenFound() {
+ int negativeId = -1; // TODO adjust test id if needed
+ String newName = "BoundaryName";
+ String newDesc = "BoundaryDescription";
+ String newMusic = "BoundaryMusic";
+ MusicModel musicToUpdate = mock(MusicModel.class);
+ when(MusicRepo.findById(negativeId)).thenReturn(musicToUpdate);
+ String result = controller.updateMusicById(negativeId, newName, newDesc, newMusic);
+ assertEquals((String) "Música Alterada!", (String) result);
+ verify(MusicRepo, times(1)).findById(negativeId);
+ verify(musicToUpdate, times(1)).setMusic((String) newMusic);
+ verify(musicToUpdate, times(1)).setMusicDescription((String) newDesc);
+ verify(musicToUpdate, times(1)).setMusicName((String) newName);
+ verify(MusicRepo, times(1)).save(same(musicToUpdate));
+ verifyNoMoreInteractions(MusicRepo);
+ }
+
+}
\ No newline at end of file