Files
query-orchestration/api/queryAPI/eulaAdminHandlers_private_test.go
Jay Brown 62b5de5722 Merged in bug/eula-email (pull request #212)
fix eula issue when email not present in jwt

* bug fix
2026-02-26 21:46:00 +00:00

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
}