This is an automated email from the ASF dual-hosted git repository.

warren pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git


The following commit(s) were added to refs/heads/main by this push:
     new d4a195761 fix(q_dev): fix task logging (#8503)
d4a195761 is described below

commit d4a19576182b61b3db17460058f3ccba946e991a
Author: DiscreteTom <[email protected]>
AuthorDate: Mon Aug 4 20:23:16 2025 +0800

    fix(q_dev): fix task logging (#8503)
---
 backend/plugins/q_dev/api/connection_test.go       |   4 +-
 backend/plugins/q_dev/impl/impl.go                 |   1 +
 .../migrationscripts/archived/user_metrics.go      |   3 +-
 backend/plugins/q_dev/models/user_data_test.go     |  98 +++++------
 backend/plugins/q_dev/tasks/s3_data_extractor.go   |  21 ++-
 .../plugins/q_dev/tasks/s3_data_extractor_test.go  | 188 ++++++++++++++-------
 6 files changed, 190 insertions(+), 125 deletions(-)

diff --git a/backend/plugins/q_dev/api/connection_test.go 
b/backend/plugins/q_dev/api/connection_test.go
index 916fbd155..6c39dee3f 100644
--- a/backend/plugins/q_dev/api/connection_test.go
+++ b/backend/plugins/q_dev/api/connection_test.go
@@ -231,11 +231,11 @@ func TestConnectionSanitization_PreservesIdentityStore(t 
*testing.T) {
 
        // Secret should be sanitized
        assert.NotEqual(t, "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", 
sanitized.SecretAccessKey)
-       
+
        // Identity Store fields should be preserved
        assert.Equal(t, "d-1234567890", sanitized.IdentityStoreId)
        assert.Equal(t, "us-west-2", sanitized.IdentityStoreRegion)
-       
+
        // Other fields should be preserved
        assert.Equal(t, "AKIAIOSFODNN7EXAMPLE", sanitized.AccessKeyId)
        assert.Equal(t, "us-east-1", sanitized.Region)
diff --git a/backend/plugins/q_dev/impl/impl.go 
b/backend/plugins/q_dev/impl/impl.go
index 5cf8bf393..b2568334b 100644
--- a/backend/plugins/q_dev/impl/impl.go
+++ b/backend/plugins/q_dev/impl/impl.go
@@ -19,6 +19,7 @@ package impl
 
 import (
        "fmt"
+
        "github.com/apache/incubator-devlake/core/context"
        "github.com/apache/incubator-devlake/core/dal"
        "github.com/apache/incubator-devlake/core/errors"
diff --git 
a/backend/plugins/q_dev/models/migrationscripts/archived/user_metrics.go 
b/backend/plugins/q_dev/models/migrationscripts/archived/user_metrics.go
index d26b75aea..be948feea 100644
--- a/backend/plugins/q_dev/models/migrationscripts/archived/user_metrics.go
+++ b/backend/plugins/q_dev/models/migrationscripts/archived/user_metrics.go
@@ -18,8 +18,9 @@ limitations under the License.
 package archived
 
 import (
-       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
        "time"
+
+       
"github.com/apache/incubator-devlake/core/models/migrationscripts/archived"
 )
 
 // QDevUserMetrics 存储按用户聚合的指标数据
diff --git a/backend/plugins/q_dev/models/user_data_test.go 
b/backend/plugins/q_dev/models/user_data_test.go
index d45d1748f..74d5dfcfe 100644
--- a/backend/plugins/q_dev/models/user_data_test.go
+++ b/backend/plugins/q_dev/models/user_data_test.go
@@ -20,7 +20,7 @@ package models
 import (
        "testing"
        "time"
-       
+
        "github.com/stretchr/testify/assert"
 )
 
@@ -28,59 +28,59 @@ func TestQDevUserDataAllMetrics(t *testing.T) {
        // Create a test user data object with all metrics
        userData := &QDevUserData{
                ConnectionId: 1,
-               UserId: "test-user-id",
-               Date: time.Now(),
-               DisplayName: "Test User",
-               
+               UserId:       "test-user-id",
+               Date:         time.Now(),
+               DisplayName:  "Test User",
+
                // Set values for existing metrics
-               CodeReview_FindingsCount: 10,
-               CodeReview_SucceededEventCount: 11,
-               InlineChat_AcceptanceEventCount: 12,
-               InlineChat_AcceptedLineAdditions: 13,
-               InlineChat_AcceptedLineDeletions: 14,
-               InlineChat_DismissalEventCount: 15,
+               CodeReview_FindingsCount:          10,
+               CodeReview_SucceededEventCount:    11,
+               InlineChat_AcceptanceEventCount:   12,
+               InlineChat_AcceptedLineAdditions:  13,
+               InlineChat_AcceptedLineDeletions:  14,
+               InlineChat_DismissalEventCount:    15,
                InlineChat_DismissedLineAdditions: 16,
                InlineChat_DismissedLineDeletions: 17,
-               InlineChat_RejectedLineAdditions: 18,
-               InlineChat_RejectedLineDeletions: 19,
-               InlineChat_RejectionEventCount: 20,
-               InlineChat_TotalEventCount: 21,
-               Inline_AICodeLines: 22,
-               Inline_AcceptanceCount: 23,
-               Inline_SuggestionsCount: 24,
-               
+               InlineChat_RejectedLineAdditions:  18,
+               InlineChat_RejectedLineDeletions:  19,
+               InlineChat_RejectionEventCount:    20,
+               InlineChat_TotalEventCount:        21,
+               Inline_AICodeLines:                22,
+               Inline_AcceptanceCount:            23,
+               Inline_SuggestionsCount:           24,
+
                // Set values for new metrics
-               Chat_AICodeLines: 25,
-               Chat_MessagesInteracted: 26,
-               Chat_MessagesSent: 27,
-               CodeFix_AcceptanceEventCount: 28,
-               CodeFix_AcceptedLines: 29,
-               CodeFix_GeneratedLines: 30,
-               CodeFix_GenerationEventCount: 31,
-               CodeReview_FailedEventCount: 32,
-               Dev_AcceptanceEventCount: 33,
-               Dev_AcceptedLines: 34,
-               Dev_GeneratedLines: 35,
-               Dev_GenerationEventCount: 36,
-               DocGeneration_AcceptedFileUpdates: 37,
+               Chat_AICodeLines:                     25,
+               Chat_MessagesInteracted:              26,
+               Chat_MessagesSent:                    27,
+               CodeFix_AcceptanceEventCount:         28,
+               CodeFix_AcceptedLines:                29,
+               CodeFix_GeneratedLines:               30,
+               CodeFix_GenerationEventCount:         31,
+               CodeReview_FailedEventCount:          32,
+               Dev_AcceptanceEventCount:             33,
+               Dev_AcceptedLines:                    34,
+               Dev_GeneratedLines:                   35,
+               Dev_GenerationEventCount:             36,
+               DocGeneration_AcceptedFileUpdates:    37,
                DocGeneration_AcceptedFilesCreations: 38,
-               DocGeneration_AcceptedLineAdditions: 39,
-               DocGeneration_AcceptedLineUpdates: 40,
-               DocGeneration_EventCount: 41,
-               DocGeneration_RejectedFileCreations: 42,
-               DocGeneration_RejectedFileUpdates: 43,
-               DocGeneration_RejectedLineAdditions: 44,
-               DocGeneration_RejectedLineUpdates: 45,
-               TestGeneration_AcceptedLines: 46,
-               TestGeneration_AcceptedTests: 47,
-               TestGeneration_EventCount: 48,
-               TestGeneration_GeneratedLines: 49,
-               TestGeneration_GeneratedTests: 50,
-               Transformation_EventCount: 51,
-               Transformation_LinesGenerated: 52,
-               Transformation_LinesIngested: 53,
+               DocGeneration_AcceptedLineAdditions:  39,
+               DocGeneration_AcceptedLineUpdates:    40,
+               DocGeneration_EventCount:             41,
+               DocGeneration_RejectedFileCreations:  42,
+               DocGeneration_RejectedFileUpdates:    43,
+               DocGeneration_RejectedLineAdditions:  44,
+               DocGeneration_RejectedLineUpdates:    45,
+               TestGeneration_AcceptedLines:         46,
+               TestGeneration_AcceptedTests:         47,
+               TestGeneration_EventCount:            48,
+               TestGeneration_GeneratedLines:        49,
+               TestGeneration_GeneratedTests:        50,
+               Transformation_EventCount:            51,
+               Transformation_LinesGenerated:        52,
+               Transformation_LinesIngested:         53,
        }
-       
+
        // Verify that all metrics are accessible
        // Existing metrics
        assert.Equal(t, 10, userData.CodeReview_FindingsCount)
@@ -98,7 +98,7 @@ func TestQDevUserDataAllMetrics(t *testing.T) {
        assert.Equal(t, 22, userData.Inline_AICodeLines)
        assert.Equal(t, 23, userData.Inline_AcceptanceCount)
        assert.Equal(t, 24, userData.Inline_SuggestionsCount)
-       
+
        // New metrics
        assert.Equal(t, 25, userData.Chat_AICodeLines)
        assert.Equal(t, 26, userData.Chat_MessagesInteracted)
diff --git a/backend/plugins/q_dev/tasks/s3_data_extractor.go 
b/backend/plugins/q_dev/tasks/s3_data_extractor.go
index f091e15b9..10ab6a7cd 100644
--- a/backend/plugins/q_dev/tasks/s3_data_extractor.go
+++ b/backend/plugins/q_dev/tasks/s3_data_extractor.go
@@ -119,7 +119,7 @@ func processCSVData(taskCtx plugin.SubTaskContext, db 
dal.Dal, reader io.ReadClo
 
        // 读取标头
        headers, err := csvReader.Read()
-       fmt.Printf("headers: %+v\n", headers)
+       taskCtx.GetLogger().Debug("CSV headers: %+v", headers)
        if err != nil {
                return errors.Convert(err)
        }
@@ -135,7 +135,7 @@ func processCSVData(taskCtx plugin.SubTaskContext, db 
dal.Dal, reader io.ReadClo
                }
 
                // 创建用户数据对象 (updated to include display name resolution)
-               userData, err := createUserDataWithDisplayName(headers, record, 
fileMeta, data.IdentityClient)
+               userData, err := 
createUserDataWithDisplayName(taskCtx.GetLogger(), headers, record, fileMeta, 
data.IdentityClient)
                if err != nil {
                        return errors.Default.Wrap(err, "failed to create user 
data")
                }
@@ -156,7 +156,9 @@ type UserDisplayNameResolver interface {
 }
 
 // 从CSV记录创建用户数据对象 (enhanced with display name resolution)
-func createUserDataWithDisplayName(headers []string, record []string, fileMeta 
*models.QDevS3FileMeta, identityClient UserDisplayNameResolver) 
(*models.QDevUserData, errors.Error) {
+func createUserDataWithDisplayName(logger interface {
+       Debug(format string, a ...interface{})
+}, headers []string, record []string, fileMeta *models.QDevS3FileMeta, 
identityClient UserDisplayNameResolver) (*models.QDevUserData, errors.Error) {
        userData := &models.QDevUserData{
                ConnectionId: fileMeta.ConnectionId,
        }
@@ -165,13 +167,12 @@ func createUserDataWithDisplayName(headers []string, 
record []string, fileMeta *
        fieldMap := make(map[string]string)
        for i, header := range headers {
                if i < len(record) {
-                       // 打印每个header和对应的值,帮助调试
-                       fmt.Printf("Mapping header[%d]: '%s' -> '%s'\n", i, 
header, record[i])
+                       logger.Debug("Mapping header[%d]: '%s' -> '%s'", i, 
header, record[i])
                        fieldMap[header] = record[i]
                        // 同时添加去除空格的版本
                        trimmedHeader := strings.TrimSpace(header)
                        if trimmedHeader != header {
-                               fmt.Printf("Also adding trimmed header: 
'%s'\n", trimmedHeader)
+                               logger.Debug("Also adding trimmed header: 
'%s'", trimmedHeader)
                                fieldMap[trimmedHeader] = record[i]
                        }
                }
@@ -188,7 +189,7 @@ func createUserDataWithDisplayName(headers []string, record 
[]string, fileMeta *
        }
 
        // 设置DisplayName (new functionality)
-       userData.DisplayName = resolveDisplayName(userData.UserId, 
identityClient)
+       userData.DisplayName = resolveDisplayName(logger, userData.UserId, 
identityClient)
 
        // 设置Date
        dateStr, ok := fieldMap["Date"]
@@ -251,7 +252,9 @@ func createUserDataWithDisplayName(headers []string, record 
[]string, fileMeta *
 }
 
 // resolveDisplayName resolves user ID to display name using Identity Client
-func resolveDisplayName(userId string, identityClient UserDisplayNameResolver) 
string {
+func resolveDisplayName(logger interface {
+       Debug(format string, a ...interface{})
+}, userId string, identityClient UserDisplayNameResolver) string {
        // If no identity client available, use userId as fallback
        if identityClient == nil {
                return userId
@@ -261,7 +264,7 @@ func resolveDisplayName(userId string, identityClient 
UserDisplayNameResolver) s
        displayName, err := identityClient.ResolveUserDisplayName(userId)
        if err != nil {
                // Log error but continue with userId as fallback
-               fmt.Printf("Failed to resolve display name for user %s: %v\n", 
userId, err)
+               logger.Debug("Failed to resolve display name for user %s: %v", 
userId, err)
                return userId
        }
 
diff --git a/backend/plugins/q_dev/tasks/s3_data_extractor_test.go 
b/backend/plugins/q_dev/tasks/s3_data_extractor_test.go
index 1e84e81ef..fbea299dc 100644
--- a/backend/plugins/q_dev/tasks/s3_data_extractor_test.go
+++ b/backend/plugins/q_dev/tasks/s3_data_extractor_test.go
@@ -40,18 +40,32 @@ func (m *MockIdentityClient) ResolveUserDisplayName(userId 
string) (string, erro
 // Ensure MockIdentityClient implements UserDisplayNameResolver
 var _ UserDisplayNameResolver = (*MockIdentityClient)(nil)
 
+// MockLogger is a mock implementation of the logger interface for testing
+type MockLogger struct {
+       mock.Mock
+}
+
+func (m *MockLogger) Debug(format string, args ...interface{}) {
+       m.Called(format, args)
+}
+
 func TestCreateUserDataWithDisplayName_Success(t *testing.T) {
        headers := []string{"UserId", "Date", "CodeReview_FindingsCount", 
"Inline_AcceptanceCount"}
        record := []string{"user-123", "2025-06-23", "5", "10"}
        fileMeta := &models.QDevS3FileMeta{
                ConnectionId: 1,
        }
-       
+
        mockIdentityClient := &MockIdentityClient{}
        mockIdentityClient.On("ResolveUserDisplayName", 
"user-123").Return("John Doe", nil)
-       
-       userData, err := createUserDataWithDisplayName(headers, record, 
fileMeta, mockIdentityClient)
-       
+
+       mockLogger := &MockLogger{}
+       // Add expectations for Debug calls
+       mockLogger.On("Debug", "Mapping header[%d]: '%s' -> '%s'", 
mock.Anything).Return()
+       mockLogger.On("Debug", "Also adding trimmed header: '%s'", 
mock.Anything).Return()
+
+       userData, err := createUserDataWithDisplayName(mockLogger, headers, 
record, fileMeta, mockIdentityClient)
+
        assert.NoError(t, err)
        assert.NotNil(t, userData)
        assert.Equal(t, "user-123", userData.UserId)
@@ -59,7 +73,7 @@ func TestCreateUserDataWithDisplayName_Success(t *testing.T) {
        assert.Equal(t, uint64(1), userData.ConnectionId)
        assert.Equal(t, 5, userData.CodeReview_FindingsCount)
        assert.Equal(t, 10, userData.Inline_AcceptanceCount)
-       
+
        mockIdentityClient.AssertExpectations(t)
 }
 
@@ -69,17 +83,23 @@ func TestCreateUserDataWithDisplayName_FallbackToUUID(t 
*testing.T) {
        fileMeta := &models.QDevS3FileMeta{
                ConnectionId: 1,
        }
-       
+
        mockIdentityClient := &MockIdentityClient{}
        mockIdentityClient.On("ResolveUserDisplayName", 
"user-456").Return("user-456", assert.AnError)
-       
-       userData, err := createUserDataWithDisplayName(headers, record, 
fileMeta, mockIdentityClient)
-       
+
+       mockLogger := &MockLogger{}
+       // Add expectations for Debug calls
+       mockLogger.On("Debug", "Mapping header[%d]: '%s' -> '%s'", 
mock.Anything).Return()
+       mockLogger.On("Debug", "Also adding trimmed header: '%s'", 
mock.Anything).Return()
+       mockLogger.On("Debug", "Failed to resolve display name for user %s: 
%v", mock.Anything).Return()
+
+       userData, err := createUserDataWithDisplayName(mockLogger, headers, 
record, fileMeta, mockIdentityClient)
+
        assert.NoError(t, err)
        assert.NotNil(t, userData)
        assert.Equal(t, "user-456", userData.UserId)
        assert.Equal(t, "user-456", userData.DisplayName) // Should fallback to 
UUID
-       
+
        mockIdentityClient.AssertExpectations(t)
 }
 
@@ -89,9 +109,14 @@ func TestCreateUserDataWithDisplayName_NoIdentityClient(t 
*testing.T) {
        fileMeta := &models.QDevS3FileMeta{
                ConnectionId: 1,
        }
-       
-       userData, err := createUserDataWithDisplayName(headers, record, 
fileMeta, nil)
-       
+
+       mockLogger := &MockLogger{}
+       // Add expectations for Debug calls
+       mockLogger.On("Debug", "Mapping header[%d]: '%s' -> '%s'", 
mock.Anything).Return()
+       mockLogger.On("Debug", "Also adding trimmed header: '%s'", 
mock.Anything).Return()
+
+       userData, err := createUserDataWithDisplayName(mockLogger, headers, 
record, fileMeta, nil)
+
        assert.NoError(t, err)
        assert.NotNil(t, userData)
        assert.Equal(t, "user-789", userData.UserId)
@@ -104,17 +129,22 @@ func TestCreateUserDataWithDisplayName_EmptyDisplayName(t 
*testing.T) {
        fileMeta := &models.QDevS3FileMeta{
                ConnectionId: 1,
        }
-       
+
        mockIdentityClient := &MockIdentityClient{}
        mockIdentityClient.On("ResolveUserDisplayName", 
"user-empty").Return("", nil)
-       
-       userData, err := createUserDataWithDisplayName(headers, record, 
fileMeta, mockIdentityClient)
-       
+
+       mockLogger := &MockLogger{}
+       // Add expectations for Debug calls
+       mockLogger.On("Debug", "Mapping header[%d]: '%s' -> '%s'", 
mock.Anything).Return()
+       mockLogger.On("Debug", "Also adding trimmed header: '%s'", 
mock.Anything).Return()
+
+       userData, err := createUserDataWithDisplayName(mockLogger, headers, 
record, fileMeta, mockIdentityClient)
+
        assert.NoError(t, err)
        assert.NotNil(t, userData)
        assert.Equal(t, "user-empty", userData.UserId)
        assert.Equal(t, "user-empty", userData.DisplayName) // Should fallback 
when empty
-       
+
        mockIdentityClient.AssertExpectations(t)
 }
 
@@ -134,24 +164,29 @@ func 
TestCreateUserDataWithDisplayName_AllExistingMetrics(t *testing.T) {
        fileMeta := &models.QDevS3FileMeta{
                ConnectionId: 123,
        }
-       
+
        mockIdentityClient := &MockIdentityClient{}
        mockIdentityClient.On("ResolveUserDisplayName", 
"test-user").Return("Test User", nil)
-       
-       userData, err := createUserDataWithDisplayName(headers, record, 
fileMeta, mockIdentityClient)
-       
+
+       mockLogger := &MockLogger{}
+       // Add expectations for Debug calls
+       mockLogger.On("Debug", "Mapping header[%d]: '%s' -> '%s'", 
mock.Anything).Return()
+       mockLogger.On("Debug", "Also adding trimmed header: '%s'", 
mock.Anything).Return()
+
+       userData, err := createUserDataWithDisplayName(mockLogger, headers, 
record, fileMeta, mockIdentityClient)
+
        assert.NoError(t, err)
        assert.NotNil(t, userData)
-       
+
        // Verify basic fields
        assert.Equal(t, "test-user", userData.UserId)
        assert.Equal(t, "Test User", userData.DisplayName)
        assert.Equal(t, uint64(123), userData.ConnectionId)
-       
+
        // Verify date parsing
        expectedDate, _ := time.Parse("2006-01-02", "2025-06-23")
        assert.Equal(t, expectedDate, userData.Date)
-       
+
        // Verify all existing metric fields
        assert.Equal(t, 1, userData.CodeReview_FindingsCount)
        assert.Equal(t, 2, userData.CodeReview_SucceededEventCount)
@@ -168,7 +203,7 @@ func TestCreateUserDataWithDisplayName_AllExistingMetrics(t 
*testing.T) {
        assert.Equal(t, 13, userData.Inline_AICodeLines)
        assert.Equal(t, 14, userData.Inline_AcceptanceCount)
        assert.Equal(t, 15, userData.Inline_SuggestionsCount)
-       
+
        mockIdentityClient.AssertExpectations(t)
 }
 
@@ -186,30 +221,35 @@ func TestCreateUserDataWithDisplayName_AllNewMetrics(t 
*testing.T) {
                "TestGeneration_GeneratedLines", 
"TestGeneration_GeneratedTests",
                "Transformation_EventCount", "Transformation_LinesGenerated", 
"Transformation_LinesIngested",
        }
-       
+
        record := []string{
                "test-user", "2025-06-23",
                "101", "102", "103", "104", "105", "106", "107", "108", "109", 
"110",
                "111", "112", "113", "114", "115", "116", "117", "118", "119", 
"120",
                "121", "122", "123", "124", "125", "126", "127", "128", "129",
        }
-       
+
        fileMeta := &models.QDevS3FileMeta{
                ConnectionId: 123,
        }
-       
+
        mockIdentityClient := &MockIdentityClient{}
        mockIdentityClient.On("ResolveUserDisplayName", 
"test-user").Return("Test User", nil)
-       
-       userData, err := createUserDataWithDisplayName(headers, record, 
fileMeta, mockIdentityClient)
-       
+
+       mockLogger := &MockLogger{}
+       // Add expectations for Debug calls
+       mockLogger.On("Debug", "Mapping header[%d]: '%s' -> '%s'", 
mock.Anything).Return()
+       mockLogger.On("Debug", "Also adding trimmed header: '%s'", 
mock.Anything).Return()
+
+       userData, err := createUserDataWithDisplayName(mockLogger, headers, 
record, fileMeta, mockIdentityClient)
+
        assert.NoError(t, err)
        assert.NotNil(t, userData)
-       
+
        // Verify basic fields
        assert.Equal(t, "test-user", userData.UserId)
        assert.Equal(t, "Test User", userData.DisplayName)
-       
+
        // Verify all new metric fields
        assert.Equal(t, 101, userData.Chat_AICodeLines)
        assert.Equal(t, 102, userData.Chat_MessagesInteracted)
@@ -240,7 +280,7 @@ func TestCreateUserDataWithDisplayName_AllNewMetrics(t 
*testing.T) {
        assert.Equal(t, 127, userData.Transformation_EventCount)
        assert.Equal(t, 128, userData.Transformation_LinesGenerated)
        assert.Equal(t, 129, userData.Transformation_LinesIngested)
-       
+
        mockIdentityClient.AssertExpectations(t)
 }
 
@@ -248,60 +288,70 @@ func TestCreateUserDataWithDisplayName_MissingMetrics(t 
*testing.T) {
        // Only provide a few metrics in the CSV
        headers := []string{"UserId", "Date", "CodeReview_FindingsCount", 
"Chat_AICodeLines"}
        record := []string{"test-user", "2025-06-23", "42", "99"}
-       
+
        fileMeta := &models.QDevS3FileMeta{
                ConnectionId: 123,
        }
-       
+
        mockIdentityClient := &MockIdentityClient{}
        mockIdentityClient.On("ResolveUserDisplayName", 
"test-user").Return("Test User", nil)
-       
-       userData, err := createUserDataWithDisplayName(headers, record, 
fileMeta, mockIdentityClient)
-       
+
+       mockLogger := &MockLogger{}
+       // Add expectations for Debug calls
+       mockLogger.On("Debug", "Mapping header[%d]: '%s' -> '%s'", 
mock.Anything).Return()
+       mockLogger.On("Debug", "Also adding trimmed header: '%s'", 
mock.Anything).Return()
+
+       userData, err := createUserDataWithDisplayName(mockLogger, headers, 
record, fileMeta, mockIdentityClient)
+
        assert.NoError(t, err)
        assert.NotNil(t, userData)
-       
+
        // Verify provided metrics are set correctly
        assert.Equal(t, 42, userData.CodeReview_FindingsCount)
        assert.Equal(t, 99, userData.Chat_AICodeLines)
-       
+
        // Verify missing metrics are set to 0
        assert.Equal(t, 0, userData.CodeReview_SucceededEventCount)
        assert.Equal(t, 0, userData.InlineChat_AcceptanceEventCount)
        assert.Equal(t, 0, userData.Chat_MessagesInteracted)
        assert.Equal(t, 0, userData.TestGeneration_AcceptedTests)
        assert.Equal(t, 0, userData.Transformation_LinesIngested)
-       
+
        mockIdentityClient.AssertExpectations(t)
 }
 
 func TestCreateUserDataWithDisplayName_InvalidMetricValues(t *testing.T) {
        headers := []string{
-               "UserId", "Date", "CodeReview_FindingsCount", 
"Chat_AICodeLines", 
+               "UserId", "Date", "CodeReview_FindingsCount", 
"Chat_AICodeLines",
                "InlineChat_AcceptanceEventCount", 
"TestGeneration_AcceptedTests",
        }
        record := []string{"test-user", "2025-06-23", "42", "not-a-number", 
"abc", ""}
-       
+
        fileMeta := &models.QDevS3FileMeta{
                ConnectionId: 123,
        }
-       
+
        mockIdentityClient := &MockIdentityClient{}
        mockIdentityClient.On("ResolveUserDisplayName", 
"test-user").Return("Test User", nil)
-       
-       userData, err := createUserDataWithDisplayName(headers, record, 
fileMeta, mockIdentityClient)
-       
+
+       mockLogger := &MockLogger{}
+       // Add expectations for Debug calls
+       mockLogger.On("Debug", "Mapping header[%d]: '%s' -> '%s'", 
mock.Anything).Return()
+       mockLogger.On("Debug", "Also adding trimmed header: '%s'", 
mock.Anything).Return()
+
+       userData, err := createUserDataWithDisplayName(mockLogger, headers, 
record, fileMeta, mockIdentityClient)
+
        assert.NoError(t, err)
        assert.NotNil(t, userData)
-       
+
        // Verify valid metric is set correctly
        assert.Equal(t, 42, userData.CodeReview_FindingsCount)
-       
+
        // Verify invalid metrics are set to 0
        assert.Equal(t, 0, userData.Chat_AICodeLines)
        assert.Equal(t, 0, userData.InlineChat_AcceptanceEventCount)
        assert.Equal(t, 0, userData.TestGeneration_AcceptedTests)
-       
+
        mockIdentityClient.AssertExpectations(t)
 }
 
@@ -311,9 +361,14 @@ func TestCreateUserDataWithDisplayName_MissingUserId(t 
*testing.T) {
        fileMeta := &models.QDevS3FileMeta{
                ConnectionId: 1,
        }
-       
-       userData, err := createUserDataWithDisplayName(headers, record, 
fileMeta, nil)
-       
+
+       mockLogger := &MockLogger{}
+       // Add expectations for Debug calls
+       mockLogger.On("Debug", "Mapping header[%d]: '%s' -> '%s'", 
mock.Anything).Return()
+       mockLogger.On("Debug", "Also adding trimmed header: '%s'", 
mock.Anything).Return()
+
+       userData, err := createUserDataWithDisplayName(mockLogger, headers, 
record, fileMeta, nil)
+
        assert.Error(t, err)
        assert.Nil(t, userData)
        assert.Contains(t, err.Error(), "UserId not found")
@@ -325,9 +380,14 @@ func TestCreateUserDataWithDisplayName_MissingDate(t 
*testing.T) {
        fileMeta := &models.QDevS3FileMeta{
                ConnectionId: 1,
        }
-       
-       userData, err := createUserDataWithDisplayName(headers, record, 
fileMeta, nil)
-       
+
+       mockLogger := &MockLogger{}
+       // Add expectations for Debug calls
+       mockLogger.On("Debug", "Mapping header[%d]: '%s' -> '%s'", 
mock.Anything).Return()
+       mockLogger.On("Debug", "Also adding trimmed header: '%s'", 
mock.Anything).Return()
+
+       userData, err := createUserDataWithDisplayName(mockLogger, headers, 
record, fileMeta, nil)
+
        assert.Error(t, err)
        assert.Nil(t, userData)
        assert.Contains(t, err.Error(), "Date not found")
@@ -346,10 +406,10 @@ func TestParseDate(t *testing.T) {
                {"2025-07-10T15:04:05Z", time.Date(2025, 7, 10, 15, 4, 5, 0, 
time.UTC), false},
                {"invalid-date", time.Time{}, true},
        }
-       
+
        for _, tc := range testCases {
                date, err := parseDate(tc.dateStr)
-               
+
                if tc.expectError {
                        assert.Error(t, err)
                } else {
@@ -361,13 +421,13 @@ func TestParseDate(t *testing.T) {
 
 func TestParseInt(t *testing.T) {
        fieldMap := map[string]string{
-               "ValidInt": "42",
-               "ZeroInt": "0",
+               "ValidInt":    "42",
+               "ZeroInt":     "0",
                "NegativeInt": "-10",
-               "InvalidInt": "not-a-number",
+               "InvalidInt":  "not-a-number",
                "EmptyString": "",
        }
-       
+
        assert.Equal(t, 42, parseInt(fieldMap, "ValidInt"))
        assert.Equal(t, 0, parseInt(fieldMap, "ZeroInt"))
        assert.Equal(t, -10, parseInt(fieldMap, "NegativeInt"))

Reply via email to