62b5de5722
fix eula issue when email not present in jwt * bug fix
176 lines
5.8 KiB
Go
176 lines
5.8 KiB
Go
package queryapi
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
"time"
|
|
|
|
"queryorchestration/internal/database/repository"
|
|
"queryorchestration/internal/eula"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestConvertAgreementToAPI_NonEmailIdentifier verifies that agreements stored with
|
|
// non-email identifiers (username or subject ID fallbacks) serialize to JSON without error.
|
|
// This is the fix for bug #1: non-email userEmail values caused 500 on GET /admin/eula/agreements.
|
|
func TestConvertAgreementToAPI_NonEmailIdentifier(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
userEmail string
|
|
}{
|
|
{name: "valid email", userEmail: "user@example.com"},
|
|
{name: "username fallback", userEmail: "accessuser"},
|
|
{name: "subject ID fallback", userEmail: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"},
|
|
{name: "empty string", userEmail: ""},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
row := &repository.ListEulaAgreementsRow{
|
|
ID: uuid.New(),
|
|
Cognitosubjectid: "sub-123",
|
|
Useremail: tt.userEmail,
|
|
Eulaversionid: uuid.New(),
|
|
Agreedat: pgtype.Timestamptz{Time: time.Now(), Valid: true},
|
|
Agreedfromip: "192.168.1.1",
|
|
Eulaversionstring: "1.0",
|
|
}
|
|
|
|
result := convertAgreementToAPI(row)
|
|
|
|
assert.Equal(t, tt.userEmail, string(result.UserEmail))
|
|
|
|
// The critical check: JSON marshal must not fail
|
|
data, err := json.Marshal(result)
|
|
require.NoError(t, err, "JSON marshal failed for userEmail=%q", tt.userEmail)
|
|
assert.Contains(t, string(data), `"userEmail"`)
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestConvertVersionToAPI_NonEmailCreatedBy verifies that versions with non-email
|
|
// createdBy/activatedBy values serialize to JSON without error.
|
|
// This is the fix for bug #2: non-email createdBy/activatedBy caused 500 on GET /admin/eula.
|
|
func TestConvertVersionToAPI_NonEmailCreatedBy(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
createdBy string
|
|
activatedBy *string
|
|
}{
|
|
{name: "valid emails", createdBy: "admin@example.com", activatedBy: strPtr("admin@example.com")},
|
|
{name: "username createdBy", createdBy: "adminuser", activatedBy: nil},
|
|
{name: "subject createdBy", createdBy: "a1b2c3d4-e5f6-7890", activatedBy: nil},
|
|
{name: "username activatedBy", createdBy: "admin@test.com", activatedBy: strPtr("adminuser")},
|
|
{name: "both non-email", createdBy: "sysadmin", activatedBy: strPtr("opsuser")},
|
|
{name: "empty createdBy", createdBy: "", activatedBy: nil},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
version := &repository.Eulaversion{
|
|
ID: uuid.New(),
|
|
Version: "1.0",
|
|
Title: "Test EULA",
|
|
Content: "# Test content",
|
|
Createdat: pgtype.Timestamptz{Time: time.Now(), Valid: true},
|
|
Createdby: tt.createdBy,
|
|
Iscurrent: true,
|
|
}
|
|
|
|
if tt.activatedBy != nil {
|
|
version.Activatedat = pgtype.Timestamptz{Time: time.Now(), Valid: true}
|
|
version.Activatedby = tt.activatedBy
|
|
}
|
|
|
|
result := convertVersionToAPI(version)
|
|
|
|
assert.Equal(t, tt.createdBy, string(result.CreatedBy))
|
|
|
|
// The critical check: JSON marshal must not fail
|
|
data, err := json.Marshal(result)
|
|
require.NoError(t, err, "JSON marshal failed for createdBy=%q, activatedBy=%v", tt.createdBy, tt.activatedBy)
|
|
assert.Contains(t, string(data), `"createdBy"`)
|
|
|
|
if tt.activatedBy != nil {
|
|
assert.Contains(t, string(data), `"activatedBy"`)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestConvertComplianceReportToAPI_NonEmailIdentifiers verifies that compliance reports
|
|
// with non-email user identifiers serialize to JSON without error.
|
|
// This is the fix for bug #3: non-email currentEmail/email from Cognito caused 500
|
|
// on GET /admin/eula/compliance.
|
|
func TestConvertComplianceReportToAPI_NonEmailIdentifiers(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
currentEmail string
|
|
email *string
|
|
}{
|
|
{name: "valid emails", currentEmail: "user@example.com", email: strPtr("user@example.com")},
|
|
{name: "username currentEmail", currentEmail: "accessuser", email: strPtr("accessuser")},
|
|
{name: "empty currentEmail", currentEmail: "", email: nil},
|
|
{name: "subject ID currentEmail", currentEmail: "a1b2c3d4-e5f6-7890", email: strPtr("a1b2c3d4-e5f6-7890")},
|
|
{name: "mixed email and username", currentEmail: "user@example.com", email: strPtr("oldusername")},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
agreedAt := time.Now()
|
|
ip := "10.0.0.1"
|
|
user := eula.ComplianceReportUser{
|
|
CognitoSubjectID: "sub-" + uuid.New().String()[:8],
|
|
CurrentEmail: tt.currentEmail,
|
|
Agreed: tt.email != nil,
|
|
}
|
|
if tt.email != nil {
|
|
user.Email = tt.email
|
|
user.AgreedAt = &agreedAt
|
|
user.AgreedFromIP = &ip
|
|
}
|
|
|
|
result := &eula.ComplianceReportResult{
|
|
Version: &repository.Eulaversion{
|
|
ID: uuid.New(),
|
|
Version: "1.0",
|
|
Title: "Test EULA",
|
|
Content: "# Test",
|
|
Createdat: pgtype.Timestamptz{Time: time.Now(), Valid: true},
|
|
Createdby: "admin@test.com",
|
|
Iscurrent: true,
|
|
},
|
|
Summary: eula.ComplianceReportSummary{
|
|
TotalUsers: 1,
|
|
AgreedCount: 1,
|
|
NotAgreedCount: 0,
|
|
CompliancePercentage: 100.0,
|
|
},
|
|
Users: []eula.ComplianceReportUser{user},
|
|
Page: 1,
|
|
PageSize: 50,
|
|
TotalPages: 1,
|
|
TotalItems: 1,
|
|
}
|
|
|
|
report := convertComplianceReportToAPI(result)
|
|
|
|
assert.Equal(t, tt.currentEmail, string(report.Users[0].CurrentEmail))
|
|
|
|
// The critical check: JSON marshal must not fail
|
|
data, err := json.Marshal(report)
|
|
require.NoError(t, err, "JSON marshal failed for currentEmail=%q, email=%v", tt.currentEmail, tt.email)
|
|
assert.Contains(t, string(data), `"currentEmail"`)
|
|
})
|
|
}
|
|
}
|
|
|
|
// strPtr returns a pointer to the given string.
|
|
func strPtr(s string) *string {
|
|
return &s
|
|
}
|