diff --git a/adapter/presenter/_create_account_output_test.go b/adapter/presenter/_create_account_output_test.go new file mode 100644 index 0000000..d1f28e9 --- /dev/null +++ b/adapter/presenter/_create_account_output_test.go @@ -0,0 +1,228 @@ +// ********RoostGPT******** +/* +Test generated by RoostGPT for test mayankzbio-go-clean using AI Type Claude AI and AI Model claude-3-5-sonnet-20240620 + +ROOST_METHOD_HASH=Output_176178cc60 +ROOST_METHOD_SIG_HASH=Output_d83d35060a + +FUNCTION_DEF=func (a createAccountPresenter) Output(account domain.Account) usecase.CreateAccountOutput +Based on the provided function and context, here are several test scenarios for the `Output` method of the `createAccountPresenter` struct: + +``` +Scenario 1: Successful Account Output Conversion + +Details: + Description: This test verifies that the Output method correctly converts a domain.Account object to a usecase.CreateAccountOutput object with all fields properly mapped. + +Execution: + Arrange: + - Create a mock domain.Account with known values for all fields. + - Initialize a createAccountPresenter instance. + Act: + - Call the Output method with the mock account. + Assert: + - Verify that the returned usecase.CreateAccountOutput matches the expected values from the input account. + +Validation: + This test ensures that the presenter correctly translates internal domain objects to the expected output format. It's crucial for maintaining the contract between the use case and the external interfaces of the application. + +Scenario 2: Zero Balance Account Output + +Details: + Description: Test the Output method's handling of an account with a zero balance to ensure proper formatting. + +Execution: + Arrange: + - Create a mock domain.Account with a balance of 0. + - Initialize a createAccountPresenter instance. + Act: + - Call the Output method with the zero-balance account. + Assert: + - Verify that the Balance field in the output is exactly 0.0 (not a small floating-point value). + +Validation: + This test checks the precision of balance representation, which is important for financial applications where exact zero balances may have significance. + +Scenario 3: Maximum Value Handling + +Details: + Description: Verify that the Output method correctly handles an account with maximum possible values for its numeric fields. + +Execution: + Arrange: + - Create a mock domain.Account with the maximum possible balance value. + - Initialize a createAccountPresenter instance. + Act: + - Call the Output method with the maximum-value account. + Assert: + - Check that the Balance field in the output correctly represents the maximum value without loss of precision. + +Validation: + This edge case test ensures that the presenter can handle extreme values without overflow or loss of precision, which is critical for maintaining data integrity. + +Scenario 4: Proper Time Formatting + +Details: + Description: Ensure that the CreatedAt field is correctly formatted according to RFC3339 standard. + +Execution: + Arrange: + - Create a mock domain.Account with a known creation time. + - Initialize a createAccountPresenter instance. + Act: + - Call the Output method with the account. + Assert: + - Verify that the CreatedAt field in the output is a string formatted exactly as per RFC3339. + +Validation: + Consistent time formatting is crucial for interoperability and data consistency across different parts of the system or external integrations. + +Scenario 5: ID String Conversion + +Details: + Description: Test that the account ID is correctly converted to a string representation. + +Execution: + Arrange: + - Create a mock domain.Account with a known ID value. + - Initialize a createAccountPresenter instance. + Act: + - Call the Output method with the account. + Assert: + - Check that the ID field in the output is a string and matches the expected string representation of the account's ID. + +Validation: + Proper ID conversion ensures that the unique identifier of the account is preserved and correctly represented in the output format. + +Scenario 6: Empty String Handling + +Details: + Description: Verify that the Output method correctly handles an account with empty string values for name and CPF. + +Execution: + Arrange: + - Create a mock domain.Account with empty strings for Name and CPF. + - Initialize a createAccountPresenter instance. + Act: + - Call the Output method with the account containing empty strings. + Assert: + - Confirm that the Name and CPF fields in the output are empty strings, not null or undefined. + +Validation: + This test ensures that the presenter maintains data integrity even when dealing with empty input, which is important for consistent data handling and avoiding null pointer exceptions in consuming code. +``` + +These scenarios cover a range of normal operations, edge cases, and potential issues that could arise when using the `Output` method of the `createAccountPresenter`. They focus on data integrity, proper type conversion, formatting, and handling of various input conditions. +*/ + +// ********RoostGPT******** +package presenter + +import ( + "testing" + "time" + + "github.com/gsabadini/go-clean-architecture/domain" + "github.com/gsabadini/go-clean-architecture/usecase" +) + +func TestcreateAccountPresenterOutput(t *testing.T) { + tests := []struct { + name string + input domain.Account + expected usecase.CreateAccountOutput + }{ + { + name: "Successful Account Output Conversion", + input: domain.Account{ + id: "123", + name: "John Doe", + cpf: "12345678901", + balance: 1000.50, + createdAt: time.Date(2023, 5, 1, 10, 30, 0, 0, time.UTC), + }, + expected: usecase.CreateAccountOutput{ + ID: "123", + Name: "John Doe", + CPF: "12345678901", + Balance: 1000.50, + CreatedAt: "2023-05-01T10:30:00Z", + }, + }, + { + name: "Zero Balance Account Output", + input: domain.Account{ + id: "456", + name: "Jane Smith", + cpf: "98765432109", + balance: 0.0, + createdAt: time.Date(2023, 5, 2, 14, 45, 0, 0, time.UTC), + }, + expected: usecase.CreateAccountOutput{ + ID: "456", + Name: "Jane Smith", + CPF: "98765432109", + Balance: 0.0, + CreatedAt: "2023-05-02T14:45:00Z", + }, + }, + { + name: "Maximum Value Handling", + input: domain.Account{ + id: "789", + name: "Max Balance", + cpf: "11122233344", + balance: 1e18, // Example of a very large balance + createdAt: time.Date(2023, 5, 3, 9, 0, 0, 0, time.UTC), + }, + expected: usecase.CreateAccountOutput{ + ID: "789", + Name: "Max Balance", + CPF: "11122233344", + Balance: 1e18, + CreatedAt: "2023-05-03T09:00:00Z", + }, + }, + { + name: "Empty String Handling", + input: domain.Account{ + id: "101", + name: "", + cpf: "", + balance: 100.0, + createdAt: time.Date(2023, 5, 4, 12, 15, 0, 0, time.UTC), + }, + expected: usecase.CreateAccountOutput{ + ID: "101", + Name: "", + CPF: "", + Balance: 100.0, + CreatedAt: "2023-05-04T12:15:00Z", + }, + }, + } + + presenter := createAccountPresenter{} + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := presenter.Output(tt.input) + + if result.ID != tt.expected.ID { + t.Errorf("ID mismatch. Got %s, want %s", result.ID, tt.expected.ID) + } + if result.Name != tt.expected.Name { + t.Errorf("Name mismatch. Got %s, want %s", result.Name, tt.expected.Name) + } + if result.CPF != tt.expected.CPF { + t.Errorf("CPF mismatch. Got %s, want %s", result.CPF, tt.expected.CPF) + } + if result.Balance != tt.expected.Balance { + t.Errorf("Balance mismatch. Got %f, want %f", result.Balance, tt.expected.Balance) + } + if result.CreatedAt != tt.expected.CreatedAt { + t.Errorf("CreatedAt mismatch. Got %s, want %s", result.CreatedAt, tt.expected.CreatedAt) + } + }) + } +} diff --git a/adapter/presenter/_create_transfer_newcreatetransferpresenter_test.go b/adapter/presenter/_create_transfer_newcreatetransferpresenter_test.go new file mode 100644 index 0000000..f93318e --- /dev/null +++ b/adapter/presenter/_create_transfer_newcreatetransferpresenter_test.go @@ -0,0 +1,167 @@ +// ********RoostGPT******** +/* +Test generated by RoostGPT for test mayankzbio-go-clean using AI Type Claude AI and AI Model claude-3-5-sonnet-20240620 + +ROOST_METHOD_HASH=NewCreateTransferPresenter_33f736514b +ROOST_METHOD_SIG_HASH=NewCreateTransferPresenter_b55d5650f6 + +FUNCTION_DEF=func NewCreateTransferPresenter() usecase.CreateTransferPresenter +Existing Test Information: +These test cases are already implemented and not included for test generation scenario: +File: go-clean-architecture/adapter/presenter/create_transfer_test.go +Test Cases: + [Test_createTransferPresenter_Output] + +Based on the provided function and context, here are several test scenarios for the `NewCreateTransferPresenter` function: + +Scenario 1: Create a New Transfer Presenter Successfully + +Details: + Description: This test verifies that the NewCreateTransferPresenter function returns a valid CreateTransferPresenter interface. +Execution: + Arrange: No specific arrangement needed as the function doesn't take any parameters. + Act: Call NewCreateTransferPresenter() and store the result. + Assert: Check that the returned value is not nil and implements the usecase.CreateTransferPresenter interface. +Validation: + The assertion ensures that the function returns a non-nil value that satisfies the CreateTransferPresenter interface. This is crucial to confirm that the returned object can be used as expected in the application. + +Scenario 2: Verify Returned Presenter Type + +Details: + Description: This test checks if the returned presenter is of the correct underlying type (createTransferPresenter). +Execution: + Arrange: No specific arrangement needed. + Act: Call NewCreateTransferPresenter() and store the result. + Assert: Use type assertion to check if the returned value is of type createTransferPresenter. +Validation: + This test ensures that the correct concrete type is being returned, which is important for maintaining consistency in the codebase and avoiding potential type-related issues. + +Scenario 3: Test Output Method of Returned Presenter + +Details: + Description: This scenario tests the Output method of the returned presenter to ensure it correctly formats a Transfer object. +Execution: + Arrange: Create a sample domain.Transfer object with known values. + Act: Call NewCreateTransferPresenter() to get a presenter, then call its Output method with the sample Transfer. + Assert: Verify that the returned CreateTransferOutput matches the expected format and values. +Validation: + This test is crucial to ensure that the presenter correctly translates domain objects into the expected output format, which is a key responsibility of the presenter in the clean architecture. + +Scenario 4: Consistency of Multiple Calls + +Details: + Description: This test checks if multiple calls to NewCreateTransferPresenter return consistent results. +Execution: + Arrange: No specific arrangement needed. + Act: Call NewCreateTransferPresenter() multiple times and store the results. + Assert: Compare the returned presenters to ensure they are functionally equivalent. +Validation: + This test ensures that the function behaves consistently across multiple invocations, which is important for reliability in a production environment. + +Scenario 5: Performance Test (Optional) + +Details: + Description: This scenario measures the performance of creating multiple presenters. +Execution: + Arrange: Set up a benchmark test. + Act: Call NewCreateTransferPresenter() in a loop for a large number of iterations. + Assert: Measure and report the time taken. +Validation: + While not strictly necessary for functionality, this test can help identify any unexpected performance issues in presenter creation, which could be important in high-load scenarios. + +These scenarios cover the creation of the presenter, its type, functionality, consistency, and performance. They ensure that the NewCreateTransferPresenter function works as expected in various situations, providing a comprehensive test suite for this part of the application. +*/ + +// ********RoostGPT******** +package presenter + +import ( + "reflect" + "testing" + "time" + + "github.com/gsabadini/go-clean-architecture/domain" + "github.com/gsabadini/go-clean-architecture/usecase" +) + +func TestNewCreateTransferPresenter(t *testing.T) { + tests := []struct { + name string + want usecase.CreateTransferPresenter + }{ + { + name: "Create a New Transfer Presenter Successfully", + want: createTransferPresenter{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := NewCreateTransferPresenter() + + if got == nil { + t.Error("NewCreateTransferPresenter() returned nil") + } + + if _, ok := got.(usecase.CreateTransferPresenter); !ok { + t.Error("Returned value does not implement usecase.CreateTransferPresenter") + } + + if reflect.TypeOf(got) != reflect.TypeOf(createTransferPresenter{}) { + t.Errorf("Expected type %T, got %T", createTransferPresenter{}, got) + } + + // Test Output method + transfer := domain.Transfer{ + id: func() domain.TransferID { return "test-id" }, + accountOriginID: func() domain.AccountID { return "origin-id" }, + accountDestinationID: func() domain.AccountID { return "destination-id" }, + amount: func() domain.Money { return 100.0 }, + createdAt: func() time.Time { return time.Now() }, + } + + output := got.Output(transfer) + + if output.ID != transfer.id() { + t.Errorf("Expected ID %s, got %s", transfer.id(), output.ID) + } + if output.AccountOriginID != transfer.accountOriginID() { + t.Errorf("Expected AccountOriginID %s, got %s", transfer.accountOriginID(), output.AccountOriginID) + } + if output.AccountDestinationID != transfer.accountDestinationID() { + t.Errorf("Expected AccountDestinationID %s, got %s", transfer.accountDestinationID(), output.AccountDestinationID) + } + if output.Amount != float64(transfer.amount()) { + t.Errorf("Expected Amount %.2f, got %.2f", transfer.amount(), output.Amount) + } + if output.CreatedAt != transfer.createdAt().Format(time.RFC3339) { + t.Errorf("Expected CreatedAt %v, got %v", transfer.createdAt().Format(time.RFC3339), output.CreatedAt) + } + }) + } + + // Test consistency of multiple calls + t.Run("Consistency of Multiple Calls", func(t *testing.T) { + presenter1 := NewCreateTransferPresenter() + presenter2 := NewCreateTransferPresenter() + + if reflect.TypeOf(presenter1) != reflect.TypeOf(presenter2) { + t.Errorf("Inconsistent types: %T vs %T", presenter1, presenter2) + } + + transfer := domain.Transfer{ + id: func() domain.TransferID { return "test-id" }, + accountOriginID: func() domain.AccountID { return "origin-id" }, + accountDestinationID: func() domain.AccountID { return "destination-id" }, + amount: func() domain.Money { return 100.0 }, + createdAt: func() time.Time { return time.Now() }, + } + + output1 := presenter1.Output(transfer) + output2 := presenter2.Output(transfer) + + if !reflect.DeepEqual(output1, output2) { + t.Error("Inconsistent output from multiple presenters") + } + }) +} diff --git a/adapter/presenter/_create_transfer_output_test.go b/adapter/presenter/_create_transfer_output_test.go new file mode 100644 index 0000000..a67f193 --- /dev/null +++ b/adapter/presenter/_create_transfer_output_test.go @@ -0,0 +1,283 @@ +// ********RoostGPT******** +/* +Test generated by RoostGPT for test mayankzbio-go-clean using AI Type Claude AI and AI Model claude-3-5-sonnet-20240620 + +ROOST_METHOD_HASH=Output_b4dd5ccd4f +ROOST_METHOD_SIG_HASH=Output_639eeea89e + +FUNCTION_DEF=func (c createTransferPresenter) Output(transfer domain.Transfer) usecase.CreateTransferOutput +Based on the provided function and context, here are several test scenarios for the `Output` method of the `createTransferPresenter` struct: + +``` +Scenario 1: Valid Transfer Output + +Details: + Description: Test that the Output method correctly transforms a valid domain.Transfer object into a usecase.CreateTransferOutput object with all fields properly mapped. + +Execution: + Arrange: + - Create a mock domain.Transfer object with known values for all fields. + - Initialize a createTransferPresenter instance. + Act: + - Call the Output method with the mock Transfer object. + Assert: + - Verify that the returned CreateTransferOutput object has all fields matching the input Transfer object. + - Check that the CreatedAt field is correctly formatted as RFC3339. + +Validation: + This test ensures that the basic functionality of the Output method works as expected, correctly mapping all fields from the domain model to the use case output model. It's crucial for maintaining the consistency between the internal domain representation and the external API response. + +Scenario 2: Zero Amount Transfer + +Details: + Description: Verify that the Output method correctly handles a Transfer with a zero amount. + +Execution: + Arrange: + - Create a mock domain.Transfer object with an amount of 0. + - Initialize a createTransferPresenter instance. + Act: + - Call the Output method with the zero-amount Transfer object. + Assert: + - Verify that the Amount field in the returned CreateTransferOutput is exactly 0.0. + +Validation: + This test checks the edge case of a zero-amount transfer, ensuring that the presenter doesn't modify or reject such transfers. It's important for scenarios where zero-amount transfers might be valid in the business logic. + +Scenario 3: Large Amount Transfer + +Details: + Description: Test the Output method's handling of a Transfer with a very large amount to check for potential floating-point precision issues. + +Execution: + Arrange: + - Create a mock domain.Transfer object with a very large amount (e.g., 999999999.99). + - Initialize a createTransferPresenter instance. + Act: + - Call the Output method with the large-amount Transfer object. + Assert: + - Verify that the Amount field in the returned CreateTransferOutput matches the input amount exactly. + +Validation: + This test ensures that the presenter can handle large monetary values without loss of precision. It's crucial for financial applications where accuracy is paramount. + +Scenario 4: Transfer with Minimum Valid IDs + +Details: + Description: Verify that the Output method correctly handles a Transfer with minimum length valid IDs for all ID fields. + +Execution: + Arrange: + - Create a mock domain.Transfer object with minimum length valid IDs for TransferID, AccountOriginID, and AccountDestinationID. + - Initialize a createTransferPresenter instance. + Act: + - Call the Output method with the prepared Transfer object. + Assert: + - Verify that all ID fields in the returned CreateTransferOutput are correctly stringified versions of the input IDs. + +Validation: + This test checks the presenter's ability to handle edge cases with minimal valid IDs, ensuring that no truncation or modification occurs during the transformation process. + +Scenario 5: Transfer with Maximum Valid IDs + +Details: + Description: Test the Output method's handling of a Transfer with maximum length valid IDs for all ID fields. + +Execution: + Arrange: + - Create a mock domain.Transfer object with maximum length valid IDs for TransferID, AccountOriginID, and AccountDestinationID. + - Initialize a createTransferPresenter instance. + Act: + - Call the Output method with the prepared Transfer object. + Assert: + - Verify that all ID fields in the returned CreateTransferOutput are correctly stringified versions of the input IDs, without any truncation. + +Validation: + This test ensures that the presenter can handle large IDs without issues, which is important for maintaining data integrity and avoiding potential bugs with ID handling in the system. + +Scenario 6: Transfer with Past Timestamp + +Details: + Description: Verify that the Output method correctly formats a Transfer with a past timestamp. + +Execution: + Arrange: + - Create a mock domain.Transfer object with a CreatedAt time set to a known past date and time. + - Initialize a createTransferPresenter instance. + Act: + - Call the Output method with the prepared Transfer object. + Assert: + - Verify that the CreatedAt field in the returned CreateTransferOutput is correctly formatted as RFC3339 and matches the input time. + +Validation: + This test ensures that the presenter correctly handles and formats past timestamps, which is crucial for maintaining accurate historical records of transfers. + +Scenario 7: Transfer with Future Timestamp + +Details: + Description: Test the Output method's handling of a Transfer with a future timestamp. + +Execution: + Arrange: + - Create a mock domain.Transfer object with a CreatedAt time set to a known future date and time. + - Initialize a createTransferPresenter instance. + Act: + - Call the Output method with the prepared Transfer object. + Assert: + - Verify that the CreatedAt field in the returned CreateTransferOutput is correctly formatted as RFC3339 and matches the input future time. + +Validation: + This test checks that the presenter can handle future timestamps without modification, which might be important for scheduled or queued transfers in the system. +``` + +These test scenarios cover a range of normal operations, edge cases, and potential error conditions for the `Output` method of the `createTransferPresenter` struct. They aim to ensure that the method correctly transforms `domain.Transfer` objects into `usecase.CreateTransferOutput` objects under various conditions, maintaining data integrity and proper formatting throughout the process. +*/ + +// ********RoostGPT******** +package presenter + +import ( + "testing" + "time" + + "github.com/gsabadini/go-clean-architecture/domain" + "github.com/gsabadini/go-clean-architecture/usecase" +) + +func TestcreateTransferPresenterOutput(t *testing.T) { + tests := []struct { + name string + transfer domain.Transfer + want usecase.CreateTransferOutput + }{ + { + name: "Valid Transfer Output", + transfer: domain.Transfer{ + id: domain.TransferID("transfer123"), + accountOriginID: domain.AccountID("origin456"), + accountDestinationID: domain.AccountID("dest789"), + amount: domain.Money(10050), // 100.50 * 100 + createdAt: time.Date(2023, 5, 1, 10, 30, 0, 0, time.UTC), + }, + want: usecase.CreateTransferOutput{ + ID: "transfer123", + AccountOriginID: "origin456", + AccountDestinationID: "dest789", + Amount: 100.50, + CreatedAt: "2023-05-01T10:30:00Z", + }, + }, + { + name: "Zero Amount Transfer", + transfer: domain.Transfer{ + id: domain.TransferID("transfer000"), + accountOriginID: domain.AccountID("origin111"), + accountDestinationID: domain.AccountID("dest222"), + amount: domain.Money(0), + createdAt: time.Date(2023, 5, 2, 15, 45, 0, 0, time.UTC), + }, + want: usecase.CreateTransferOutput{ + ID: "transfer000", + AccountOriginID: "origin111", + AccountDestinationID: "dest222", + Amount: 0, + CreatedAt: "2023-05-02T15:45:00Z", + }, + }, + { + name: "Large Amount Transfer", + transfer: domain.Transfer{ + id: domain.TransferID("transfer999"), + accountOriginID: domain.AccountID("origin888"), + accountDestinationID: domain.AccountID("dest777"), + amount: domain.Money(99999999999), // 999999999.99 * 100 + createdAt: time.Date(2023, 5, 3, 20, 0, 0, 0, time.UTC), + }, + want: usecase.CreateTransferOutput{ + ID: "transfer999", + AccountOriginID: "origin888", + AccountDestinationID: "dest777", + Amount: 999999999.99, + CreatedAt: "2023-05-03T20:00:00Z", + }, + }, + { + name: "Transfer with Minimum Valid IDs", + transfer: domain.Transfer{ + id: domain.TransferID("t1"), + accountOriginID: domain.AccountID("o1"), + accountDestinationID: domain.AccountID("d1"), + amount: domain.Money(5025), // 50.25 * 100 + createdAt: time.Date(2023, 5, 4, 9, 15, 0, 0, time.UTC), + }, + want: usecase.CreateTransferOutput{ + ID: "t1", + AccountOriginID: "o1", + AccountDestinationID: "d1", + Amount: 50.25, + CreatedAt: "2023-05-04T09:15:00Z", + }, + }, + { + name: "Transfer with Maximum Valid IDs", + transfer: domain.Transfer{ + id: domain.TransferID("transfer1234567890123456789012345678901234567890"), + accountOriginID: domain.AccountID("origin12345678901234567890123456789012345678901"), + accountDestinationID: domain.AccountID("dest123456789012345678901234567890123456789012"), + amount: domain.Money(7575), // 75.75 * 100 + createdAt: time.Date(2023, 5, 5, 14, 30, 0, 0, time.UTC), + }, + want: usecase.CreateTransferOutput{ + ID: "transfer1234567890123456789012345678901234567890", + AccountOriginID: "origin12345678901234567890123456789012345678901", + AccountDestinationID: "dest123456789012345678901234567890123456789012", + Amount: 75.75, + CreatedAt: "2023-05-05T14:30:00Z", + }, + }, + { + name: "Transfer with Past Timestamp", + transfer: domain.Transfer{ + id: domain.TransferID("transfer_past"), + accountOriginID: domain.AccountID("origin_past"), + accountDestinationID: domain.AccountID("dest_past"), + amount: domain.Money(20000), // 200.00 * 100 + createdAt: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC), + }, + want: usecase.CreateTransferOutput{ + ID: "transfer_past", + AccountOriginID: "origin_past", + AccountDestinationID: "dest_past", + Amount: 200.00, + CreatedAt: "2020-01-01T00:00:00Z", + }, + }, + { + name: "Transfer with Future Timestamp", + transfer: domain.Transfer{ + id: domain.TransferID("transfer_future"), + accountOriginID: domain.AccountID("origin_future"), + accountDestinationID: domain.AccountID("dest_future"), + amount: domain.Money(30000), // 300.00 * 100 + createdAt: time.Date(2025, 12, 31, 23, 59, 59, 0, time.UTC), + }, + want: usecase.CreateTransferOutput{ + ID: "transfer_future", + AccountOriginID: "origin_future", + AccountDestinationID: "dest_future", + Amount: 300.00, + CreatedAt: "2025-12-31T23:59:59Z", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := createTransferPresenter{} + got := c.Output(tt.transfer) + if got != tt.want { + t.Errorf("createTransferPresenter.Output() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/adapter/presenter/_find_all_account_newfindallaccountpresenter_test.go b/adapter/presenter/_find_all_account_newfindallaccountpresenter_test.go new file mode 100644 index 0000000..c5daeea --- /dev/null +++ b/adapter/presenter/_find_all_account_newfindallaccountpresenter_test.go @@ -0,0 +1,138 @@ +// ********RoostGPT******** +/* +Test generated by RoostGPT for test mayankzbio-go-clean using AI Type Claude AI and AI Model claude-3-5-sonnet-20240620 + +ROOST_METHOD_HASH=NewFindAllAccountPresenter_25f1f615e9 +ROOST_METHOD_SIG_HASH=NewFindAllAccountPresenter_feaa71619a + +FUNCTION_DEF=func NewFindAllAccountPresenter() usecase.FindAllAccountPresenter +Existing Test Information: +These test cases are already implemented and not included for test generation scenario: +File: go-clean-architecture/adapter/presenter/find_all_account_test.go +Test Cases: + [Test_findAllAccountPresenter_Output] + +Based on the provided function and context, here are some test scenarios for the `NewFindAllAccountPresenter` function: + +Scenario 1: Create a new FindAllAccountPresenter instance + +Details: + Description: This test verifies that the NewFindAllAccountPresenter function returns a valid instance of usecase.FindAllAccountPresenter. + +Execution: + Arrange: No specific arrangement needed. + Act: Call NewFindAllAccountPresenter(). + Assert: Check that the returned value is not nil and implements the usecase.FindAllAccountPresenter interface. + +Validation: + This test ensures that the factory function correctly creates and returns an object that adheres to the expected interface. It's crucial for maintaining the contract between different layers of the application. + +Scenario 2: Verify the type of the returned presenter + +Details: + Description: This test checks if the returned presenter is of the correct underlying type (findAllAccountPresenter). + +Execution: + Arrange: No specific arrangement needed. + Act: Call NewFindAllAccountPresenter(). + Assert: Use type assertion to confirm that the returned value is of type findAllAccountPresenter. + +Validation: + Ensuring the correct concrete type is returned is important for maintaining the expected behavior and capabilities of the presenter in the application. + +Scenario 3: Test the idempotency of NewFindAllAccountPresenter + +Details: + Description: This test verifies that multiple calls to NewFindAllAccountPresenter return functionally equivalent instances. + +Execution: + Arrange: No specific arrangement needed. + Act: Call NewFindAllAccountPresenter() twice. + Assert: Compare the two returned instances to ensure they are functionally equivalent (though not necessarily the same instance). + +Validation: + This test ensures consistency in the creation of presenters, which is important for predictable behavior across the application, especially in scenarios where multiple presenters might be created. + +Scenario 4: Verify the presenter implements the Output method + +Details: + Description: This test checks if the returned presenter correctly implements the Output method as defined in the usecase.FindAllAccountPresenter interface. + +Execution: + Arrange: Create a slice of domain.Account objects. + Act: Call NewFindAllAccountPresenter() to get a presenter, then call its Output method with the prepared accounts. + Assert: Verify that the Output method exists and can be called without panicking. + +Validation: + This test ensures that the presenter adheres to the interface contract, which is crucial for the proper functioning of the use case layer that depends on this presenter. + +These scenarios cover the basic functionality of the NewFindAllAccountPresenter function, focusing on its ability to create a valid presenter instance that adheres to the expected interface and type. The actual behavior of the Output method is not tested here, as it's not part of the NewFindAllAccountPresenter function's responsibility. +*/ + +// ********RoostGPT******** +package presenter + +import ( + "reflect" + "testing" + "time" + + "github.com/gsabadini/go-clean-architecture/domain" + "github.com/gsabadini/go-clean-architecture/usecase" +) + +func TestNewFindAllAccountPresenter(t *testing.T) { + tests := []struct { + name string + want usecase.FindAllAccountPresenter + }{ + { + name: "Create a new FindAllAccountPresenter instance", + want: findAllAccountPresenter{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Scenario 1: Create a new FindAllAccountPresenter instance + got := NewFindAllAccountPresenter() + if got == nil { + t.Error("NewFindAllAccountPresenter() returned nil") + } + + // Scenario 2: Verify the type of the returned presenter + if _, ok := got.(findAllAccountPresenter); !ok { + t.Errorf("NewFindAllAccountPresenter() returned wrong type: got %T, want findAllAccountPresenter", got) + } + + // Scenario 3: Test the idempotency of NewFindAllAccountPresenter + got2 := NewFindAllAccountPresenter() + if !reflect.DeepEqual(got, got2) { + t.Errorf("Multiple calls to NewFindAllAccountPresenter() returned different results") + } + + // Scenario 4: Verify the presenter implements the Output method + accounts := []domain.Account{ + { + id: domain.AccountID("1"), + name: "John Doe", + cpf: "12345678901", + balance: domain.Money(1000.0), + createdAt: time.Now(), + }, + } + + // Use a recover function to catch any panics + defer func() { + if r := recover(); r != nil { + t.Errorf("Output method panicked: %v", r) + } + }() + + // Call the Output method + _ = got.Output(accounts) + + // If we reach here, it means the Output method exists and didn't panic + }) + } +} diff --git a/adapter/presenter/_find_all_account_output_test.go b/adapter/presenter/_find_all_account_output_test.go new file mode 100644 index 0000000..2d1ac9c --- /dev/null +++ b/adapter/presenter/_find_all_account_output_test.go @@ -0,0 +1,229 @@ +// ********RoostGPT******** +/* +Test generated by RoostGPT for test mayankzbio-go-clean using AI Type Claude AI and AI Model claude-3-5-sonnet-20240620 + +ROOST_METHOD_HASH=Output_7bcd1fa1d0 +ROOST_METHOD_SIG_HASH=Output_1f9cab4653 + +FUNCTION_DEF=func (a findAllAccountPresenter) Output(accounts []domain.Account) []usecase.FindAllAccountOutput +Based on the provided function and context, here are several test scenarios for the `Output` method of the `findAllAccountPresenter` struct: + +``` +Scenario 1: Empty Account List + +Details: + Description: Test the behavior when an empty slice of accounts is passed to the Output method. +Execution: + Arrange: Create an empty slice of domain.Account. + Act: Call the Output method with the empty slice. + Assert: Verify that the returned slice of FindAllAccountOutput is also empty. +Validation: + This test ensures that the function correctly handles an empty input, returning an empty output slice rather than nil or panicking. It's important for robustness and avoiding nil pointer exceptions in the calling code. + +Scenario 2: Single Account Conversion + +Details: + Description: Test the conversion of a single domain.Account to FindAllAccountOutput. +Execution: + Arrange: Create a slice with one domain.Account, populating all fields with known values. + Act: Call the Output method with this single-item slice. + Assert: Verify that the returned slice contains exactly one FindAllAccountOutput item with all fields correctly converted from the input Account. +Validation: + This test checks the basic functionality of the conversion process, ensuring all fields are correctly mapped and formatted. It's crucial for verifying the core purpose of the function. + +Scenario 3: Multiple Accounts Conversion + +Details: + Description: Test the conversion of multiple domain.Account objects to FindAllAccountOutput. +Execution: + Arrange: Create a slice with multiple domain.Account objects, each with unique values. + Act: Call the Output method with this multi-item slice. + Assert: Verify that the returned slice contains the correct number of FindAllAccountOutput items, each correctly converted from its corresponding input Account. +Validation: + This test ensures the function can handle multiple accounts correctly, maintaining order and accurately converting each account. It's important for real-world usage where multiple accounts are common. + +Scenario 4: Time Format Verification + +Details: + Description: Specifically test the conversion of the CreatedAt field to ensure it's formatted correctly as RFC3339. +Execution: + Arrange: Create a domain.Account with a known CreatedAt time. + Act: Call the Output method with a slice containing this account. + Assert: Verify that the CreatedAt field in the resulting FindAllAccountOutput is correctly formatted as RFC3339. +Validation: + This test focuses on the time formatting aspect, which is crucial for consistent date representation in the API output. It ensures compliance with the specified RFC3339 format. + +Scenario 5: Balance Precision + +Details: + Description: Test the conversion of the Balance field to ensure floating-point precision is maintained. +Execution: + Arrange: Create a domain.Account with a Balance that has decimal places (e.g., 100.50). + Act: Call the Output method with a slice containing this account. + Assert: Verify that the Balance field in the resulting FindAllAccountOutput maintains the correct precision. +Validation: + This test is important for financial applications where precise balance representation is crucial. It ensures that no rounding errors or precision loss occurs during the conversion. + +Scenario 6: Large Number of Accounts + +Details: + Description: Test the function's performance and correctness with a large number of accounts. +Execution: + Arrange: Create a slice with a large number of domain.Account objects (e.g., 10,000). + Act: Call the Output method with this large slice. + Assert: Verify that all accounts are correctly converted and the operation completes within an acceptable time frame. +Validation: + This test checks the function's ability to handle large datasets efficiently, which is important for scalability. It ensures there are no performance bottlenecks or memory issues with larger inputs. + +Scenario 7: Null or Zero Values Handling + +Details: + Description: Test how the function handles accounts with null or zero values in some fields. +Execution: + Arrange: Create domain.Account objects with some fields set to zero values (empty strings, zero time, etc.). + Act: Call the Output method with a slice containing these accounts. + Assert: Verify that the function correctly handles these zero values, converting them to appropriate representations in FindAllAccountOutput. +Validation: + This test ensures robustness in handling various input data conditions, including potentially uninitialized or default values. It's important for preventing unexpected behavior or errors when dealing with incomplete data. +``` + +These scenarios cover a range of cases from basic functionality to edge cases and performance considerations, providing a comprehensive test suite for the `Output` method. +*/ + +// ********RoostGPT******** +package presenter + +import ( + "reflect" + "testing" + "time" + + "github.com/gsabadini/go-clean-architecture/domain" + "github.com/gsabadini/go-clean-architecture/usecase" +) + +func TestfindAllAccountPresenterOutput(t *testing.T) { + tests := []struct { + name string + accounts []domain.Account + want []usecase.FindAllAccountOutput + }{ + { + name: "Empty Account List", + accounts: []domain.Account{}, + want: []usecase.FindAllAccountOutput{}, + }, + { + name: "Single Account Conversion", + accounts: []domain.Account{ + domain.NewAccount("acc123", "John Doe", "12345678900", domain.NewMoney(10050), time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)), + }, + want: []usecase.FindAllAccountOutput{ + { + ID: "acc123", + Name: "John Doe", + CPF: "12345678900", + Balance: 100.50, + CreatedAt: "2023-01-01T00:00:00Z", + }, + }, + }, + { + name: "Multiple Accounts Conversion", + accounts: []domain.Account{ + domain.NewAccount("acc123", "John Doe", "12345678900", domain.NewMoney(10050), time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)), + domain.NewAccount("acc456", "Jane Smith", "98765432100", domain.NewMoney(20075), time.Date(2023, 2, 1, 0, 0, 0, 0, time.UTC)), + }, + want: []usecase.FindAllAccountOutput{ + { + ID: "acc123", + Name: "John Doe", + CPF: "12345678900", + Balance: 100.50, + CreatedAt: "2023-01-01T00:00:00Z", + }, + { + ID: "acc456", + Name: "Jane Smith", + CPF: "98765432100", + Balance: 200.75, + CreatedAt: "2023-02-01T00:00:00Z", + }, + }, + }, + { + name: "Time Format Verification", + accounts: []domain.Account{ + domain.NewAccount("acc789", "Alice Johnson", "11122233344", domain.NewMoney(30000), time.Date(2023, 3, 15, 14, 30, 45, 0, time.UTC)), + }, + want: []usecase.FindAllAccountOutput{ + { + ID: "acc789", + Name: "Alice Johnson", + CPF: "11122233344", + Balance: 300.00, + CreatedAt: "2023-03-15T14:30:45Z", + }, + }, + }, + { + name: "Balance Precision", + accounts: []domain.Account{ + domain.NewAccount("acc101", "Bob Williams", "55566677788", domain.NewMoney(15075), time.Date(2023, 4, 1, 0, 0, 0, 0, time.UTC)), + }, + want: []usecase.FindAllAccountOutput{ + { + ID: "acc101", + Name: "Bob Williams", + CPF: "55566677788", + Balance: 150.75, + CreatedAt: "2023-04-01T00:00:00Z", + }, + }, + }, + { + name: "Null or Zero Values Handling", + accounts: []domain.Account{ + domain.NewAccount("", "", "", domain.NewMoney(0), time.Time{}), + }, + want: []usecase.FindAllAccountOutput{ + { + ID: "", + Name: "", + CPF: "", + Balance: 0, + CreatedAt: "0001-01-01T00:00:00Z", + }, + }, + }, + } + + presenter := findAllAccountPresenter{} + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := presenter.Output(tt.accounts) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Output() = %v, want %v", got, tt.want) + } + }) + } +} + +// NewAccount is a helper function to create a new Account +// This function should be defined in the domain package, but for testing purposes, we define it here +func NewAccount(id, name, cpf string, balance domain.Money, createdAt time.Time) domain.Account { + return domain.Account{ + ID: domain.AccountID(id), + Name: name, + CPF: cpf, + Balance: balance, + CreatedAt: createdAt, + } +} + +// NewMoney is a helper function to create a new Money value +// This function should be defined in the domain package, but for testing purposes, we define it here +func NewMoney(amount int64) domain.Money { + return domain.Money(amount) +} diff --git a/adapter/presenter/_find_all_transfer_newfindalltransferpresenter_test.go b/adapter/presenter/_find_all_transfer_newfindalltransferpresenter_test.go new file mode 100644 index 0000000..7fbb911 --- /dev/null +++ b/adapter/presenter/_find_all_transfer_newfindalltransferpresenter_test.go @@ -0,0 +1,197 @@ +// ********RoostGPT******** +/* +Test generated by RoostGPT for test mayankzbio-go-clean using AI Type Claude AI and AI Model claude-3-5-sonnet-20240620 + +ROOST_METHOD_HASH=NewFindAllTransferPresenter_f203834708 +ROOST_METHOD_SIG_HASH=NewFindAllTransferPresenter_ea74041f7d + +FUNCTION_DEF=func NewFindAllTransferPresenter() usecase.FindAllTransferPresenter +Existing Test Information: +These test cases are already implemented and not included for test generation scenario: +File: go-clean-architecture/adapter/presenter/find_all_transfer_test.go +Test Cases: + [Test_findAllTransferPresenter_Output] + +Based on the provided function and context, here are several test scenarios for the `NewFindAllTransferPresenter` function: + +Scenario 1: Create a new FindAllTransferPresenter instance + +Details: + Description: This test verifies that the NewFindAllTransferPresenter function returns a valid instance of usecase.FindAllTransferPresenter. + +Execution: + Arrange: No specific arrangement needed. + Act: Call NewFindAllTransferPresenter(). + Assert: Check that the returned value is not nil and implements the usecase.FindAllTransferPresenter interface. + +Validation: + This test ensures that the factory function correctly creates and returns an object of the expected type. It's crucial for verifying that consumers of this function receive a usable presenter object. + +Scenario 2: Verify the type of the returned presenter + +Details: + Description: This test checks if the returned presenter is specifically of type findAllTransferPresenter. + +Execution: + Arrange: No specific arrangement needed. + Act: Call NewFindAllTransferPresenter(). + Assert: Use type assertion to confirm that the returned value is of type findAllTransferPresenter. + +Validation: + While the interface is what's typically used, this test ensures that the concrete type being returned is as expected. This can be important for maintaining consistency in the codebase and catching any inadvertent changes to the implementation. + +Scenario 3: Test the Output method of the returned presenter with empty input + +Details: + Description: Verify that the Output method of the returned presenter handles an empty slice of transfers correctly. + +Execution: + Arrange: Create an empty slice of domain.Transfer. + Act: Call NewFindAllTransferPresenter() to get a presenter, then call its Output method with the empty slice. + Assert: Verify that the result is an empty slice of usecase.FindAllTransferOutput. + +Validation: + This test ensures that the presenter can handle edge cases, such as no transfers being present. It's important for robustness and preventing potential nil pointer dereferences or other issues when working with empty data sets. + +Scenario 4: Test the Output method with a single transfer + +Details: + Description: Check if the Output method correctly transforms a single domain.Transfer into a usecase.FindAllTransferOutput. + +Execution: + Arrange: Create a slice with one domain.Transfer object. + Act: Get a presenter using NewFindAllTransferPresenter() and call its Output method with the prepared transfer. + Assert: Verify that the result is a slice with one usecase.FindAllTransferOutput object, correctly mapping all fields from the input. + +Validation: + This test ensures that the basic transformation logic in the Output method works correctly for a single item. It's crucial for verifying the core functionality of the presenter. + +Scenario 5: Test the Output method with multiple transfers + +Details: + Description: Verify that the Output method correctly transforms multiple domain.Transfer objects into usecase.FindAllTransferOutput objects. + +Execution: + Arrange: Create a slice with multiple domain.Transfer objects. + Act: Get a presenter using NewFindAllTransferPresenter() and call its Output method with the prepared transfers. + Assert: Check that the result is a slice of usecase.FindAllTransferOutput objects, with the correct number of items and all fields properly mapped. + +Validation: + This test ensures that the presenter can handle multiple transfers correctly, which is crucial for its intended use in listing all transfers. It verifies both the transformation logic and the ability to handle collections of data. + +These scenarios cover the creation of the presenter and its basic functionality. They test the normal operation (creating the presenter and transforming data), edge cases (empty input), and implicitly cover error handling by ensuring the presenter can handle various inputs without crashing. The actual implementation of these tests would depend on the specific details of the domain.Transfer and usecase.FindAllTransferOutput structs, which are not fully provided in the given context. +*/ + +// ********RoostGPT******** +package presenter + +import ( + "reflect" + "testing" + "time" + + "github.com/gsabadini/go-clean-architecture/domain" + "github.com/gsabadini/go-clean-architecture/usecase" +) + +func TestNewFindAllTransferPresenter(t *testing.T) { + tests := []struct { + name string + input []domain.Transfer + expected []usecase.FindAllTransferOutput + }{ + { + name: "Create a new FindAllTransferPresenter instance", + input: nil, + expected: nil, + }, + { + name: "Test Output method with empty input", + input: []domain.Transfer{}, + expected: []usecase.FindAllTransferOutput{}, + }, + { + name: "Test Output method with a single transfer", + input: []domain.Transfer{ + { + id: "transfer1", + accountOriginID: "account1", + accountDestinationID: "account2", + amount: 100.0, + createdAt: time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC), + }, + }, + expected: []usecase.FindAllTransferOutput{ + { + ID: "transfer1", + AccountOriginID: "account1", + AccountDestinationID: "account2", + Amount: 100.0, + CreatedAt: "2023-01-01T00:00:00Z", + }, + }, + }, + { + name: "Test Output method with multiple transfers", + input: []domain.Transfer{ + { + id: "transfer1", + accountOriginID: "account1", + accountDestinationID: "account2", + amount: 100.0, + createdAt: time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC), + }, + { + id: "transfer2", + accountOriginID: "account3", + accountDestinationID: "account4", + amount: 200.0, + createdAt: time.Date(2023, 1, 2, 0, 0, 0, 0, time.UTC), + }, + }, + expected: []usecase.FindAllTransferOutput{ + { + ID: "transfer1", + AccountOriginID: "account1", + AccountDestinationID: "account2", + Amount: 100.0, + CreatedAt: "2023-01-01T00:00:00Z", + }, + { + ID: "transfer2", + AccountOriginID: "account3", + AccountDestinationID: "account4", + Amount: 200.0, + CreatedAt: "2023-01-02T00:00:00Z", + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + presenter := NewFindAllTransferPresenter() + + // Verify that the returned presenter is not nil and implements the interface + if presenter == nil { + t.Fatal("NewFindAllTransferPresenter returned nil") + } + if _, ok := presenter.(usecase.FindAllTransferPresenter); !ok { + t.Fatal("Returned presenter does not implement usecase.FindAllTransferPresenter") + } + + // Verify the concrete type of the presenter + if _, ok := presenter.(findAllTransferPresenter); !ok { + t.Fatal("Returned presenter is not of type findAllTransferPresenter") + } + + // Test the Output method + result := presenter.Output(tt.input) + + // Check if the result matches the expected output + if !reflect.DeepEqual(result, tt.expected) { + t.Errorf("Output() = %v, want %v", result, tt.expected) + } + }) + } +} diff --git a/adapter/presenter/_find_all_transfer_output_test.go b/adapter/presenter/_find_all_transfer_output_test.go new file mode 100644 index 0000000..af5c39b --- /dev/null +++ b/adapter/presenter/_find_all_transfer_output_test.go @@ -0,0 +1,278 @@ +// ********RoostGPT******** +/* +Test generated by RoostGPT for test mayankzbio-go-clean using AI Type Claude AI and AI Model claude-3-5-sonnet-20240620 + +ROOST_METHOD_HASH=Output_957d61659f +ROOST_METHOD_SIG_HASH=Output_7b20311995 + +FUNCTION_DEF=func (a findAllTransferPresenter) Output(transfers []domain.Transfer) []usecase.FindAllTransferOutput +Based on the provided function and context, here are several test scenarios for the `Output` method of the `findAllTransferPresenter` struct: + +``` +Scenario 1: Empty Slice of Transfers + +Details: + Description: Test the behavior when an empty slice of transfers is provided. This checks if the function correctly handles zero transfers and returns an empty slice of FindAllTransferOutput. +Execution: + Arrange: Create an empty slice of domain.Transfer. + Act: Call the Output method with the empty slice. + Assert: Verify that the returned slice is empty. +Validation: + This test ensures that the function behaves correctly with no input, returning an empty slice rather than nil or panicking. It's important for robustness and avoiding null pointer exceptions in the calling code. + +Scenario 2: Single Transfer in Slice + +Details: + Description: Test the conversion of a single domain.Transfer to FindAllTransferOutput. +Execution: + Arrange: Create a slice with one domain.Transfer object, populating all fields with known values. + Act: Call the Output method with this slice. + Assert: Verify that a slice with one FindAllTransferOutput is returned, and all fields match the input Transfer. +Validation: + This test checks the basic functionality of converting a Transfer to FindAllTransferOutput, ensuring all fields are correctly mapped and formatted. + +Scenario 3: Multiple Transfers in Slice + +Details: + Description: Test the conversion of multiple domain.Transfer objects to FindAllTransferOutput. +Execution: + Arrange: Create a slice with multiple domain.Transfer objects. + Act: Call the Output method with this slice. + Assert: Verify that the returned slice has the same length as the input and that each FindAllTransferOutput correctly represents its corresponding Transfer. +Validation: + This test ensures the function can handle multiple transfers, maintaining order and correctly converting each one. + +Scenario 4: Transfer with Zero Amount + +Details: + Description: Test the handling of a Transfer with a zero amount. +Execution: + Arrange: Create a slice with one domain.Transfer object where the amount is set to zero. + Act: Call the Output method with this slice. + Assert: Verify that the returned FindAllTransferOutput has an Amount of 0.0. +Validation: + This test checks that zero amounts are handled correctly and not mistakenly converted or rounded. + +Scenario 5: Transfer with Maximum Float64 Amount + +Details: + Description: Test the handling of a Transfer with the maximum possible float64 value as the amount. +Execution: + Arrange: Create a slice with one domain.Transfer object where the amount is set to math.MaxFloat64. + Act: Call the Output method with this slice. + Assert: Verify that the returned FindAllTransferOutput has an Amount equal to math.MaxFloat64. +Validation: + This edge case test ensures that extremely large amounts are handled without loss of precision or overflow. + +Scenario 6: Transfer with Minimum Time Value + +Details: + Description: Test the handling of a Transfer with the minimum possible time.Time value. +Execution: + Arrange: Create a slice with one domain.Transfer object where the CreatedAt is set to time.Time{} (zero value). + Act: Call the Output method with this slice. + Assert: Verify that the returned FindAllTransferOutput has a CreatedAt string formatted correctly according to RFC3339. +Validation: + This test checks the correct formatting of extreme time values, ensuring no panics occur and the format is consistent. + +Scenario 7: Transfer with Maximum Time Value + +Details: + Description: Test the handling of a Transfer with the maximum possible time.Time value. +Execution: + Arrange: Create a slice with one domain.Transfer object where the CreatedAt is set to the maximum time.Time value. + Act: Call the Output method with this slice. + Assert: Verify that the returned FindAllTransferOutput has a CreatedAt string formatted correctly according to RFC3339. +Validation: + This edge case test ensures that extremely future dates are handled and formatted correctly. + +Scenario 8: Transfers with Duplicate IDs + +Details: + Description: Test the behavior when multiple Transfers have the same ID. +Execution: + Arrange: Create a slice with multiple domain.Transfer objects, some having identical IDs. + Act: Call the Output method with this slice. + Assert: Verify that all Transfers are converted, maintaining their order and individual data, despite having duplicate IDs. +Validation: + This test checks that the function doesn't perform any deduplication or special handling for transfers with the same ID, preserving all input data. +``` + +These scenarios cover a range of normal operations, edge cases, and potential error conditions for the `Output` method. They test the function's ability to handle various input sizes, data types, and extreme values, ensuring robust and correct behavior across different scenarios. +*/ + +// ********RoostGPT******** +package presenter + +import ( + "math" + "testing" + "time" + + "github.com/gsabadini/go-clean-architecture/domain" + "github.com/gsabadini/go-clean-architecture/usecase" +) + +func TestfindAllTransferPresenterOutput(t *testing.T) { + tests := []struct { + name string + transfers []domain.Transfer + want []usecase.FindAllTransferOutput + }{ + { + name: "Empty Slice of Transfers", + transfers: []domain.Transfer{}, + want: []usecase.FindAllTransferOutput{}, + }, + { + name: "Single Transfer in Slice", + transfers: []domain.Transfer{ + newTransfer("1", "origin1", "dest1", 10050, time.Date(2023, 5, 1, 10, 0, 0, 0, time.UTC)), + }, + want: []usecase.FindAllTransferOutput{ + { + ID: "1", + AccountOriginID: "origin1", + AccountDestinationID: "dest1", + Amount: 100.50, + CreatedAt: "2023-05-01T10:00:00Z", + }, + }, + }, + { + name: "Multiple Transfers in Slice", + transfers: []domain.Transfer{ + newTransfer("1", "origin1", "dest1", 10050, time.Date(2023, 5, 1, 10, 0, 0, 0, time.UTC)), + newTransfer("2", "origin2", "dest2", 20075, time.Date(2023, 5, 2, 11, 0, 0, 0, time.UTC)), + }, + want: []usecase.FindAllTransferOutput{ + { + ID: "1", + AccountOriginID: "origin1", + AccountDestinationID: "dest1", + Amount: 100.50, + CreatedAt: "2023-05-01T10:00:00Z", + }, + { + ID: "2", + AccountOriginID: "origin2", + AccountDestinationID: "dest2", + Amount: 200.75, + CreatedAt: "2023-05-02T11:00:00Z", + }, + }, + }, + { + name: "Transfer with Zero Amount", + transfers: []domain.Transfer{ + newTransfer("1", "origin1", "dest1", 0, time.Date(2023, 5, 1, 10, 0, 0, 0, time.UTC)), + }, + want: []usecase.FindAllTransferOutput{ + { + ID: "1", + AccountOriginID: "origin1", + AccountDestinationID: "dest1", + Amount: 0.0, + CreatedAt: "2023-05-01T10:00:00Z", + }, + }, + }, + { + name: "Transfer with Maximum Float64 Amount", + transfers: []domain.Transfer{ + newTransfer("1", "origin1", "dest1", domain.Money(math.MaxFloat64*100), time.Date(2023, 5, 1, 10, 0, 0, 0, time.UTC)), + }, + want: []usecase.FindAllTransferOutput{ + { + ID: "1", + AccountOriginID: "origin1", + AccountDestinationID: "dest1", + Amount: math.MaxFloat64, + CreatedAt: "2023-05-01T10:00:00Z", + }, + }, + }, + { + name: "Transfer with Minimum Time Value", + transfers: []domain.Transfer{ + newTransfer("1", "origin1", "dest1", 10000, time.Time{}), + }, + want: []usecase.FindAllTransferOutput{ + { + ID: "1", + AccountOriginID: "origin1", + AccountDestinationID: "dest1", + Amount: 100, + CreatedAt: "0001-01-01T00:00:00Z", + }, + }, + }, + { + name: "Transfer with Maximum Time Value", + transfers: []domain.Transfer{ + newTransfer("1", "origin1", "dest1", 10000, time.Unix(1<<63-1, 999999999)), + }, + want: []usecase.FindAllTransferOutput{ + { + ID: "1", + AccountOriginID: "origin1", + AccountDestinationID: "dest1", + Amount: 100, + CreatedAt: "292277026596-12-04T15:30:07Z", + }, + }, + }, + { + name: "Transfers with Duplicate IDs", + transfers: []domain.Transfer{ + newTransfer("1", "origin1", "dest1", 10000, time.Date(2023, 5, 1, 10, 0, 0, 0, time.UTC)), + newTransfer("1", "origin2", "dest2", 20000, time.Date(2023, 5, 2, 11, 0, 0, 0, time.UTC)), + }, + want: []usecase.FindAllTransferOutput{ + { + ID: "1", + AccountOriginID: "origin1", + AccountDestinationID: "dest1", + Amount: 100, + CreatedAt: "2023-05-01T10:00:00Z", + }, + { + ID: "1", + AccountOriginID: "origin2", + AccountDestinationID: "dest2", + Amount: 200, + CreatedAt: "2023-05-02T11:00:00Z", + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + presenter := findAllTransferPresenter{} + got := presenter.Output(tt.transfers) + + if len(got) != len(tt.want) { + t.Errorf("Output() got %v items, want %v items", len(got), len(tt.want)) + return + } + + for i := range got { + if got[i] != tt.want[i] { + t.Errorf("Output()[%d] = %v, want %v", i, got[i], tt.want[i]) + } + } + }) + } +} + +// newTransfer is a helper function to create a new Transfer with the given parameters +func newTransfer(id, originID, destID string, amount domain.Money, createdAt time.Time) domain.Transfer { + return domain.Transfer{ + ID: domain.TransferID(id), + AccountOriginID: domain.AccountID(originID), + AccountDestinationID: domain.AccountID(destID), + Amount: amount, + CreatedAt: createdAt, + } +} diff --git a/adapter/presenter/create_account_newcreateaccountpresenter_test.go b/adapter/presenter/create_account_newcreateaccountpresenter_test.go new file mode 100644 index 0000000..88ce70c --- /dev/null +++ b/adapter/presenter/create_account_newcreateaccountpresenter_test.go @@ -0,0 +1,153 @@ +// ********RoostGPT******** +/* +Test generated by RoostGPT for test mayankzbio-go-clean using AI Type Claude AI and AI Model claude-3-5-sonnet-20240620 + +ROOST_METHOD_HASH=NewCreateAccountPresenter_f9e2964dc6 +ROOST_METHOD_SIG_HASH=NewCreateAccountPresenter_beb3a93c2b + +FUNCTION_DEF=func NewCreateAccountPresenter() usecase.CreateAccountPresenter +Existing Test Information: +These test cases are already implemented and not included for test generation scenario: +File: go-clean-architecture/adapter/presenter/create_account_test.go +Test Cases: + [Test_createAccountPresenter_Output] + +Based on the provided function and context, here are some test scenarios for the `NewCreateAccountPresenter` function: + +Scenario 1: Creating a New CreateAccountPresenter Instance + +Details: + Description: This test verifies that the NewCreateAccountPresenter function returns a valid instance of usecase.CreateAccountPresenter. + +Execution: + Arrange: No specific arrangement is needed as the function doesn't take any parameters. + Act: Call NewCreateAccountPresenter() and store the result. + Assert: Check that the returned value is not nil and implements the usecase.CreateAccountPresenter interface. + +Validation: + This test ensures that the factory function correctly creates and returns an object that adheres to the expected interface. It's crucial for maintaining the contract between different layers of the application. + +Scenario 2: Verifying Type of Returned Object + +Details: + Description: This test checks if the returned object is of the correct underlying type (createAccountPresenter). + +Execution: + Arrange: No specific arrangement needed. + Act: Call NewCreateAccountPresenter() and store the result. + Assert: Use type assertion to verify that the returned object is of type createAccountPresenter. + +Validation: + Ensuring the correct concrete type is returned is important for maintaining the expected behavior and structure of the application. This test helps prevent accidental changes to the implementation. + +Scenario 3: Testing Idempotency of NewCreateAccountPresenter + +Details: + Description: This test verifies that multiple calls to NewCreateAccountPresenter return functionally equivalent objects. + +Execution: + Arrange: No specific arrangement needed. + Act: Call NewCreateAccountPresenter() twice and store the results. + Assert: Compare the two results to ensure they are functionally equivalent (though not necessarily the same instance). + +Validation: + This test ensures consistency in object creation, which is important for stateless presenters. It helps maintain predictable behavior across the application. + +Scenario 4: Verifying Interface Compliance + +Details: + Description: This test ensures that the returned object fully implements the usecase.CreateAccountPresenter interface. + +Execution: + Arrange: Create a variable of type usecase.CreateAccountPresenter. + Act: Assign the result of NewCreateAccountPresenter() to this variable. + Assert: Verify that the assignment succeeds without any compile-time or runtime errors. + +Validation: + This test is crucial for ensuring that the presenter adheres to its contract, maintaining the integrity of the clean architecture design. It helps catch any accidental changes to the interface implementation. + +Scenario 5: Testing for Nil Return + +Details: + Description: This test verifies that NewCreateAccountPresenter never returns nil. + +Execution: + Arrange: No specific arrangement needed. + Act: Call NewCreateAccountPresenter(). + Assert: Check that the returned value is not nil. + +Validation: + Ensuring that the function always returns a valid object is crucial for preventing nil pointer exceptions and maintaining robust error handling throughout the application. + +These scenarios cover the basic functionality, type checking, consistency, and interface compliance of the NewCreateAccountPresenter function. They help ensure that the function behaves as expected within the clean architecture design of the application. +*/ + +// ********RoostGPT******** + + +package presenter + +import ( + "reflect" + "testing" + "github.com/gsabadini/go-clean-architecture/usecase" +) + + + + + + + +func TestNewCreateAccountPresenter(t *testing.T) { + tests := []struct { + name string + want usecase.CreateAccountPresenter + }{ + { + name: "Creating a New CreateAccountPresenter Instance", + want: createAccountPresenter{}, + }, + { + name: "Verifying Type of Returned Object", + want: createAccountPresenter{}, + }, + { + name: "Testing Idempotency of NewCreateAccountPresenter", + want: createAccountPresenter{}, + }, + { + name: "Verifying Interface Compliance", + want: createAccountPresenter{}, + }, + { + name: "Testing for Nil Return", + want: createAccountPresenter{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := NewCreateAccountPresenter() + + if got == nil { + t.Errorf("NewCreateAccountPresenter() returned nil") + } + + if _, ok := got.(usecase.CreateAccountPresenter); !ok { + t.Errorf("NewCreateAccountPresenter() did not return an object implementing usecase.CreateAccountPresenter") + } + + if reflect.TypeOf(got) != reflect.TypeOf(tt.want) { + t.Errorf("NewCreateAccountPresenter() returned wrong type = %v, want %v", reflect.TypeOf(got), reflect.TypeOf(tt.want)) + } + + got2 := NewCreateAccountPresenter() + if !reflect.DeepEqual(got, got2) { + t.Errorf("Multiple calls to NewCreateAccountPresenter() returned different results") + } + + var _ usecase.CreateAccountPresenter = got + }) + } +} diff --git a/adapter/presenter/find_account_balance_newfindaccountbalancepresenter_test.go b/adapter/presenter/find_account_balance_newfindaccountbalancepresenter_test.go new file mode 100644 index 0000000..968a1ce --- /dev/null +++ b/adapter/presenter/find_account_balance_newfindaccountbalancepresenter_test.go @@ -0,0 +1,125 @@ +// ********RoostGPT******** +/* +Test generated by RoostGPT for test mayankzbio-go-clean using AI Type Claude AI and AI Model claude-3-5-sonnet-20240620 + +ROOST_METHOD_HASH=NewFindAccountBalancePresenter_88efb05633 +ROOST_METHOD_SIG_HASH=NewFindAccountBalancePresenter_2503b3e0c5 + +FUNCTION_DEF=func NewFindAccountBalancePresenter() usecase.FindAccountBalancePresenter +Existing Test Information: +These test cases are already implemented and not included for test generation scenario: +File: go-clean-architecture/adapter/presenter/find_account_balance_test.go +Test Cases: + [TestNewFindAccountBalancePresenter + Test_findAccountBalancePresenter_Output] + +Based on the provided function and context, here are some test scenarios for the `NewFindAccountBalancePresenter` function: + +Scenario 1: Return a valid FindAccountBalancePresenter instance + +Details: + Description: This test verifies that NewFindAccountBalancePresenter returns a valid instance of usecase.FindAccountBalancePresenter. +Execution: + Arrange: No specific arrangement needed. + Act: Call NewFindAccountBalancePresenter(). + Assert: Check that the returned value is not nil and implements the usecase.FindAccountBalancePresenter interface. +Validation: + This test ensures that the function returns a usable presenter object. It's crucial to verify that the returned object implements the correct interface, as it will be used in other parts of the application that expect a FindAccountBalancePresenter. + +Scenario 2: Verify type of returned presenter + +Details: + Description: This test checks if the returned presenter is of the correct underlying type (findAccountBalancePresenter). +Execution: + Arrange: No specific arrangement needed. + Act: Call NewFindAccountBalancePresenter(). + Assert: Use type assertion to confirm that the returned value is of type findAccountBalancePresenter. +Validation: + While the interface is important for loose coupling, verifying the concrete type ensures that the correct implementation is being used. This helps maintain the expected behavior of the presenter throughout the application. + +Scenario 3: Consistency of returned presenter instances + +Details: + Description: This test checks if multiple calls to NewFindAccountBalancePresenter return functionally equivalent instances. +Execution: + Arrange: No specific arrangement needed. + Act: Call NewFindAccountBalancePresenter() twice. + Assert: Compare the two returned instances to ensure they are functionally equivalent (have the same behavior). +Validation: + This test ensures that the function consistently returns presenters with the same behavior, which is important for maintaining predictable application behavior regardless of when or where the presenter is created. + +Scenario 4: Verify presenter's Output method existence + +Details: + Description: This test checks if the returned presenter has a functional Output method as defined in the FindAccountBalancePresenter interface. +Execution: + Arrange: Create a presenter using NewFindAccountBalancePresenter(). + Act: Attempt to call the Output method with a sample domain.Money value. + Assert: Verify that the method call compiles and executes without panicking. +Validation: + This test ensures that the returned presenter adheres to the FindAccountBalancePresenter interface by having a functional Output method. It's crucial for maintaining the contract between the presenter and its users. + +Note: The actual implementation of these tests would require writing Go test code, which was not requested. These scenarios provide a framework for creating comprehensive tests for the NewFindAccountBalancePresenter function, covering its basic functionality, type correctness, consistency, and interface compliance. +*/ + +// ********RoostGPT******** + + +package presenter + +import ( + "reflect" + "testing" + "github.com/gsabadini/go-clean-architecture/domain" + "github.com/gsabadini/go-clean-architecture/usecase" +) + + + + + + + +func TestNewFindAccountBalancePresenter(t *testing.T) { + tests := []struct { + name string + want usecase.FindAccountBalancePresenter + }{ + { + name: "Return a valid FindAccountBalancePresenter instance", + want: findAccountBalancePresenter{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := NewFindAccountBalancePresenter() + + if got == nil { + t.Error("NewFindAccountBalancePresenter() returned nil") + } + if _, ok := got.(usecase.FindAccountBalancePresenter); !ok { + t.Error("Returned instance does not implement usecase.FindAccountBalancePresenter") + } + + if reflect.TypeOf(got) != reflect.TypeOf(findAccountBalancePresenter{}) { + t.Errorf("Expected type findAccountBalancePresenter, got %T", got) + } + + got2 := NewFindAccountBalancePresenter() + if !reflect.DeepEqual(got, got2) { + t.Error("Multiple calls to NewFindAccountBalancePresenter() returned different instances") + } + + func() { + defer func() { + if r := recover(); r != nil { + t.Error("Panic occurred when calling Output method") + } + }() + + _ = got.Output(domain.Money(0)) + }() + }) + } +} diff --git a/adapter/presenter/find_account_balance_output_test.go b/adapter/presenter/find_account_balance_output_test.go new file mode 100644 index 0000000..931a2fb --- /dev/null +++ b/adapter/presenter/find_account_balance_output_test.go @@ -0,0 +1,153 @@ +// ********RoostGPT******** +/* +Test generated by RoostGPT for test mayankzbio-go-clean using AI Type Claude AI and AI Model claude-3-5-sonnet-20240620 + +ROOST_METHOD_HASH=Output_f23b9296f4 +ROOST_METHOD_SIG_HASH=Output_7815e4b7d8 + +FUNCTION_DEF=func (a findAccountBalancePresenter) Output(balance domain.Money) usecase.FindAccountBalanceOutput +Based on the provided function and context, here are several test scenarios for the `Output` method of the `findAccountBalancePresenter` struct: + +``` +Scenario 1: Positive Balance Conversion + +Details: + Description: Test that the Output method correctly converts a positive domain.Money value to a usecase.FindAccountBalanceOutput struct with the correct balance. +Execution: + Arrange: Create a domain.Money instance with a positive value. + Act: Call the Output method of findAccountBalancePresenter with the created domain.Money. + Assert: Verify that the returned usecase.FindAccountBalanceOutput contains the correct balance value. +Validation: + This test ensures that the presenter correctly handles positive balances, which is a common scenario in account balance retrieval. It validates the core functionality of the Output method. + +Scenario 2: Zero Balance Conversion + +Details: + Description: Verify that the Output method correctly handles a zero balance, converting it to a usecase.FindAccountBalanceOutput struct. +Execution: + Arrange: Create a domain.Money instance with a zero value. + Act: Call the Output method of findAccountBalancePresenter with the zero-value domain.Money. + Assert: Check that the returned usecase.FindAccountBalanceOutput has a balance of exactly 0. +Validation: + Testing zero balance is important to ensure the presenter handles this edge case correctly, as accounts with no funds are a valid state in many systems. + +Scenario 3: Negative Balance Conversion + +Details: + Description: Test the Output method's behavior when given a negative domain.Money value, ensuring it's correctly represented in the output. +Execution: + Arrange: Create a domain.Money instance with a negative value. + Act: Invoke the Output method of findAccountBalancePresenter with the negative domain.Money. + Assert: Confirm that the returned usecase.FindAccountBalanceOutput contains the correct negative balance. +Validation: + This test is crucial for systems that allow negative balances (e.g., overdraft facilities). It ensures the presenter accurately represents negative amounts. + +Scenario 4: Large Balance Conversion + +Details: + Description: Verify that the Output method correctly handles and converts a very large balance without loss of precision. +Execution: + Arrange: Create a domain.Money instance with a very large value (e.g., billions). + Act: Call the Output method of findAccountBalancePresenter with the large domain.Money value. + Assert: Ensure the returned usecase.FindAccountBalanceOutput contains the exact large balance without any rounding or precision loss. +Validation: + This test is important to verify that the presenter can handle large monetary values accurately, which is critical for high-value accounts or financial systems dealing with large sums. + +Scenario 5: Small Fractional Balance Conversion + +Details: + Description: Test the Output method's ability to accurately convert and represent very small fractional monetary values. +Execution: + Arrange: Create a domain.Money instance with a very small fractional value (e.g., 0.000001). + Act: Invoke the Output method of findAccountBalancePresenter with this small fractional domain.Money. + Assert: Verify that the returned usecase.FindAccountBalanceOutput maintains the precision of the small fractional balance. +Validation: + This scenario ensures that the presenter can handle and accurately represent very small monetary amounts, which is important for systems dealing with micro-transactions or requiring high precision in financial calculations. + +Scenario 6: Consistency Across Multiple Calls + +Details: + Description: Verify that the Output method produces consistent results when called multiple times with the same input. +Execution: + Arrange: Create a domain.Money instance with any valid value. + Act: Call the Output method of findAccountBalancePresenter multiple times with the same domain.Money instance. + Assert: Check that all returned usecase.FindAccountBalanceOutput instances have identical Balance values. +Validation: + This test ensures the deterministic behavior of the Output method, which is crucial for maintaining consistency in financial data presentation across multiple API calls or user interactions. +``` + +These scenarios cover a range of possible inputs and edge cases for the `Output` method, ensuring comprehensive testing of its functionality within the context of the account balance presentation use case. +*/ + +// ********RoostGPT******** + + +package presenter + +import ( + "testing" + "github.com/gsabadini/go-clean-architecture/domain" + "github.com/gsabadini/go-clean-architecture/usecase" +) + + + + + + + +func TestfindAccountBalancePresenterOutput(t *testing.T) { + tests := []struct { + name string + balance domain.Money + want usecase.FindAccountBalanceOutput + }{ + { + name: "Positive Balance Conversion", + balance: domain.Money(10050), + want: usecase.FindAccountBalanceOutput{Balance: 100.50}, + }, + { + name: "Zero Balance Conversion", + balance: domain.Money(0), + want: usecase.FindAccountBalanceOutput{Balance: 0}, + }, + { + name: "Negative Balance Conversion", + balance: domain.Money(-5075), + want: usecase.FindAccountBalanceOutput{Balance: -50.75}, + }, + { + name: "Large Balance Conversion", + balance: domain.Money(100000000000), + want: usecase.FindAccountBalanceOutput{Balance: 1000000000.00}, + }, + { + name: "Small Fractional Balance Conversion", + balance: domain.Money(0), + want: usecase.FindAccountBalanceOutput{Balance: 0}, + }, + } + + presenter := findAccountBalancePresenter{} + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := presenter.Output(tt.balance) + if got != tt.want { + t.Errorf("Output() = %v, want %v", got, tt.want) + } + }) + } + + t.Run("Consistency Across Multiple Calls", func(t *testing.T) { + balance := domain.Money(12345) + want := usecase.FindAccountBalanceOutput{Balance: 123.45} + for i := 0; i < 3; i++ { + got := presenter.Output(balance) + if got != want { + t.Errorf("Output() call %d = %v, want %v", i+1, got, want) + } + } + }) +}