Skip to content

Commit 7bbfd13

Browse files
committed
finish tests for fastly.go
1 parent 912da10 commit 7bbfd13

File tree

1 file changed

+391
-0
lines changed

1 file changed

+391
-0
lines changed

internal/reconciler/fastlycertificatesync/fastly_test.go

Lines changed: 391 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3407,3 +3407,394 @@ func TestLogic_getFastlyTLSActivationState(t *testing.T) {
34073407
})
34083408
}
34093409
}
3410+
3411+
func TestLogic_getFastlyDomainAndConfigurationToActivationMap(t *testing.T) {
3412+
tests := []struct {
3413+
name string
3414+
inputCertificate *fastly.CustomTLSCertificate
3415+
mockActivationPages [][]*fastly.TLSActivation // Support for pagination testing
3416+
fastlyAPIError error
3417+
expectedMap map[string]map[string]*fastly.TLSActivation
3418+
expectedError string
3419+
expectedPageRequests int // Number of page requests expected
3420+
}{
3421+
{
3422+
name: "single page with multiple activations",
3423+
inputCertificate: &fastly.CustomTLSCertificate{
3424+
ID: "cert-123",
3425+
Name: "test-certificate",
3426+
Domains: []*fastly.TLSDomain{
3427+
{ID: "domain1"},
3428+
{ID: "domain2"},
3429+
},
3430+
},
3431+
mockActivationPages: [][]*fastly.TLSActivation{
3432+
// Page 1 only
3433+
{
3434+
{
3435+
ID: "activation1",
3436+
Domain: &fastly.TLSDomain{ID: "domain1"},
3437+
Configuration: &fastly.TLSConfiguration{ID: "config1"},
3438+
},
3439+
{
3440+
ID: "activation2",
3441+
Domain: &fastly.TLSDomain{ID: "domain1"},
3442+
Configuration: &fastly.TLSConfiguration{ID: "config2"},
3443+
},
3444+
{
3445+
ID: "activation3",
3446+
Domain: &fastly.TLSDomain{ID: "domain2"},
3447+
Configuration: &fastly.TLSConfiguration{ID: "config1"},
3448+
},
3449+
},
3450+
},
3451+
expectedMap: map[string]map[string]*fastly.TLSActivation{
3452+
"domain1": {
3453+
"config1": {ID: "activation1", Domain: &fastly.TLSDomain{ID: "domain1"}, Configuration: &fastly.TLSConfiguration{ID: "config1"}},
3454+
"config2": {ID: "activation2", Domain: &fastly.TLSDomain{ID: "domain1"}, Configuration: &fastly.TLSConfiguration{ID: "config2"}},
3455+
},
3456+
"domain2": {
3457+
"config1": {ID: "activation3", Domain: &fastly.TLSDomain{ID: "domain2"}, Configuration: &fastly.TLSConfiguration{ID: "config1"}},
3458+
},
3459+
},
3460+
expectedPageRequests: 1,
3461+
},
3462+
{
3463+
name: "multiple pages of activations",
3464+
inputCertificate: &fastly.CustomTLSCertificate{
3465+
ID: "cert-456",
3466+
Name: "multi-page-certificate",
3467+
Domains: []*fastly.TLSDomain{
3468+
{ID: "domain1"},
3469+
},
3470+
},
3471+
mockActivationPages: [][]*fastly.TLSActivation{
3472+
// Page 1 - full page (20 activations)
3473+
func() []*fastly.TLSActivation {
3474+
activations := make([]*fastly.TLSActivation, defaultFastlyPageSize)
3475+
for i := 0; i < defaultFastlyPageSize; i++ {
3476+
activations[i] = &fastly.TLSActivation{
3477+
ID: fmt.Sprintf("activation1_%d", i),
3478+
Domain: &fastly.TLSDomain{ID: "domain1"},
3479+
Configuration: &fastly.TLSConfiguration{ID: fmt.Sprintf("config1_%d", i)},
3480+
}
3481+
}
3482+
return activations
3483+
}(),
3484+
// Page 2 - partial page
3485+
{
3486+
{
3487+
ID: "activation2_0",
3488+
Domain: &fastly.TLSDomain{ID: "domain1"},
3489+
Configuration: &fastly.TLSConfiguration{ID: "config2_0"},
3490+
},
3491+
{
3492+
ID: "activation2_1",
3493+
Domain: &fastly.TLSDomain{ID: "domain1"},
3494+
Configuration: &fastly.TLSConfiguration{ID: "config2_1"},
3495+
},
3496+
},
3497+
},
3498+
expectedMap: func() map[string]map[string]*fastly.TLSActivation {
3499+
expectedMap := map[string]map[string]*fastly.TLSActivation{
3500+
"domain1": make(map[string]*fastly.TLSActivation),
3501+
}
3502+
// Add page 1 activations
3503+
for i := 0; i < defaultFastlyPageSize; i++ {
3504+
configID := fmt.Sprintf("config1_%d", i)
3505+
expectedMap["domain1"][configID] = &fastly.TLSActivation{
3506+
ID: fmt.Sprintf("activation1_%d", i),
3507+
Domain: &fastly.TLSDomain{ID: "domain1"},
3508+
Configuration: &fastly.TLSConfiguration{ID: configID},
3509+
}
3510+
}
3511+
// Add page 2 activations
3512+
expectedMap["domain1"]["config2_0"] = &fastly.TLSActivation{
3513+
ID: "activation2_0",
3514+
Domain: &fastly.TLSDomain{ID: "domain1"},
3515+
Configuration: &fastly.TLSConfiguration{ID: "config2_0"},
3516+
}
3517+
expectedMap["domain1"]["config2_1"] = &fastly.TLSActivation{
3518+
ID: "activation2_1",
3519+
Domain: &fastly.TLSDomain{ID: "domain1"},
3520+
Configuration: &fastly.TLSConfiguration{ID: "config2_1"},
3521+
}
3522+
return expectedMap
3523+
}(),
3524+
expectedPageRequests: 2,
3525+
},
3526+
{
3527+
name: "no activations found",
3528+
inputCertificate: &fastly.CustomTLSCertificate{
3529+
ID: "cert-789",
3530+
Name: "empty-certificate",
3531+
Domains: []*fastly.TLSDomain{
3532+
{ID: "domain1"},
3533+
},
3534+
},
3535+
mockActivationPages: [][]*fastly.TLSActivation{
3536+
// Page 1 - empty
3537+
{},
3538+
},
3539+
expectedMap: map[string]map[string]*fastly.TLSActivation{},
3540+
expectedPageRequests: 1,
3541+
},
3542+
{
3543+
name: "single activation",
3544+
inputCertificate: &fastly.CustomTLSCertificate{
3545+
ID: "cert-single",
3546+
Name: "single-activation-certificate",
3547+
Domains: []*fastly.TLSDomain{
3548+
{ID: "domain1"},
3549+
},
3550+
},
3551+
mockActivationPages: [][]*fastly.TLSActivation{
3552+
// Page 1 - single activation
3553+
{
3554+
{
3555+
ID: "only-activation",
3556+
Domain: &fastly.TLSDomain{ID: "domain1"},
3557+
Configuration: &fastly.TLSConfiguration{ID: "only-config"},
3558+
},
3559+
},
3560+
},
3561+
expectedMap: map[string]map[string]*fastly.TLSActivation{
3562+
"domain1": {
3563+
"only-config": {
3564+
ID: "only-activation",
3565+
Domain: &fastly.TLSDomain{ID: "domain1"},
3566+
Configuration: &fastly.TLSConfiguration{ID: "only-config"},
3567+
},
3568+
},
3569+
},
3570+
expectedPageRequests: 1,
3571+
},
3572+
{
3573+
name: "same domain multiple configurations",
3574+
inputCertificate: &fastly.CustomTLSCertificate{
3575+
ID: "cert-same-domain",
3576+
Name: "same-domain-certificate",
3577+
Domains: []*fastly.TLSDomain{
3578+
{ID: "domain1"},
3579+
},
3580+
},
3581+
mockActivationPages: [][]*fastly.TLSActivation{
3582+
{
3583+
{
3584+
ID: "activation1",
3585+
Domain: &fastly.TLSDomain{ID: "domain1"},
3586+
Configuration: &fastly.TLSConfiguration{ID: "config1"},
3587+
},
3588+
{
3589+
ID: "activation2",
3590+
Domain: &fastly.TLSDomain{ID: "domain1"},
3591+
Configuration: &fastly.TLSConfiguration{ID: "config2"},
3592+
},
3593+
{
3594+
ID: "activation3",
3595+
Domain: &fastly.TLSDomain{ID: "domain1"},
3596+
Configuration: &fastly.TLSConfiguration{ID: "config3"},
3597+
},
3598+
},
3599+
},
3600+
expectedMap: map[string]map[string]*fastly.TLSActivation{
3601+
"domain1": {
3602+
"config1": {ID: "activation1", Domain: &fastly.TLSDomain{ID: "domain1"}, Configuration: &fastly.TLSConfiguration{ID: "config1"}},
3603+
"config2": {ID: "activation2", Domain: &fastly.TLSDomain{ID: "domain1"}, Configuration: &fastly.TLSConfiguration{ID: "config2"}},
3604+
"config3": {ID: "activation3", Domain: &fastly.TLSDomain{ID: "domain1"}, Configuration: &fastly.TLSConfiguration{ID: "config3"}},
3605+
},
3606+
},
3607+
expectedPageRequests: 1,
3608+
},
3609+
{
3610+
name: "duplicate domain+config combination - last one wins",
3611+
inputCertificate: &fastly.CustomTLSCertificate{
3612+
ID: "cert-duplicate",
3613+
Name: "duplicate-certificate",
3614+
Domains: []*fastly.TLSDomain{
3615+
{ID: "domain1"},
3616+
},
3617+
},
3618+
mockActivationPages: [][]*fastly.TLSActivation{
3619+
{
3620+
{
3621+
ID: "activation1", // This should be overwritten
3622+
Domain: &fastly.TLSDomain{ID: "domain1"},
3623+
Configuration: &fastly.TLSConfiguration{ID: "config1"},
3624+
},
3625+
{
3626+
ID: "activation2", // This should be the final value
3627+
Domain: &fastly.TLSDomain{ID: "domain1"},
3628+
Configuration: &fastly.TLSConfiguration{ID: "config1"}, // Same domain+config as above
3629+
},
3630+
},
3631+
},
3632+
expectedMap: map[string]map[string]*fastly.TLSActivation{
3633+
"domain1": {
3634+
"config1": {ID: "activation2", Domain: &fastly.TLSDomain{ID: "domain1"}, Configuration: &fastly.TLSConfiguration{ID: "config1"}}, // Second one wins
3635+
},
3636+
},
3637+
expectedPageRequests: 1,
3638+
},
3639+
{
3640+
name: "fastly api error on first page",
3641+
inputCertificate: &fastly.CustomTLSCertificate{
3642+
ID: "cert-error",
3643+
Name: "error-certificate",
3644+
},
3645+
fastlyAPIError: errors.New("fastly api connection failed"),
3646+
expectedError: "failed to list Fastly TLS activations",
3647+
expectedPageRequests: 1,
3648+
},
3649+
{
3650+
name: "fastly api error on second page",
3651+
inputCertificate: &fastly.CustomTLSCertificate{
3652+
ID: "cert-second-page-error",
3653+
Name: "second-page-error-certificate",
3654+
},
3655+
mockActivationPages: [][]*fastly.TLSActivation{
3656+
// Page 1 - full page, successful
3657+
func() []*fastly.TLSActivation {
3658+
activations := make([]*fastly.TLSActivation, defaultFastlyPageSize)
3659+
for i := 0; i < defaultFastlyPageSize; i++ {
3660+
activations[i] = &fastly.TLSActivation{
3661+
ID: fmt.Sprintf("activation_%d", i),
3662+
Domain: &fastly.TLSDomain{ID: "domain1"},
3663+
Configuration: &fastly.TLSConfiguration{ID: fmt.Sprintf("config_%d", i)},
3664+
}
3665+
}
3666+
return activations
3667+
}(),
3668+
// Page 2 - this will return an error
3669+
},
3670+
fastlyAPIError: errors.New("second page api error"),
3671+
expectedError: "failed to list Fastly TLS activations",
3672+
expectedPageRequests: 2, // Should try to get page 2 before failing
3673+
},
3674+
}
3675+
3676+
for _, tt := range tests {
3677+
t.Run(tt.name, func(t *testing.T) {
3678+
// Track API calls
3679+
var actualPageRequests int
3680+
3681+
// Create mock Fastly client
3682+
mockFastlyClient := &MockFastlyClient{
3683+
ListTLSActivationsFunc: func(ctx context.Context, input *fastly.ListTLSActivationsInput) ([]*fastly.TLSActivation, error) {
3684+
actualPageRequests++
3685+
3686+
// Verify the correct filter is set
3687+
if input.FilterTLSCertificateID != tt.inputCertificate.ID {
3688+
t.Errorf("Expected FilterTLSCertificateID = %q, got %q", tt.inputCertificate.ID, input.FilterTLSCertificateID)
3689+
}
3690+
3691+
// Handle error cases
3692+
if tt.fastlyAPIError != nil {
3693+
// If we're testing a second-page error, only return error on page 2
3694+
if strings.Contains(tt.name, "second page error") && input.PageNumber == 2 {
3695+
return nil, tt.fastlyAPIError
3696+
} else if !strings.Contains(tt.name, "second page error") {
3697+
return nil, tt.fastlyAPIError
3698+
}
3699+
}
3700+
3701+
// Handle pagination testing with mockActivationPages
3702+
if len(tt.mockActivationPages) > 0 {
3703+
pageIndex := input.PageNumber - 1 // Convert to 0-based index
3704+
if pageIndex < len(tt.mockActivationPages) {
3705+
return tt.mockActivationPages[pageIndex], nil
3706+
}
3707+
return []*fastly.TLSActivation{}, nil // Empty page for out-of-range requests
3708+
}
3709+
3710+
// Default empty response
3711+
return []*fastly.TLSActivation{}, nil
3712+
},
3713+
}
3714+
3715+
// Create Logic instance
3716+
logic := &Logic{
3717+
FastlyClient: mockFastlyClient,
3718+
}
3719+
3720+
// Create test context
3721+
ctx := createTestContext()
3722+
3723+
// Call the function under test
3724+
result, err := logic.getFastlyDomainAndConfigurationToActivationMap(ctx, tt.inputCertificate)
3725+
3726+
// Check error expectation
3727+
if tt.expectedError != "" {
3728+
if err == nil {
3729+
t.Errorf("getFastlyDomainAndConfigurationToActivationMap() expected error containing %q, but got nil", tt.expectedError)
3730+
} else if !strings.Contains(err.Error(), tt.expectedError) {
3731+
t.Errorf("getFastlyDomainAndConfigurationToActivationMap() error = %q, want error containing %q", err.Error(), tt.expectedError)
3732+
}
3733+
return // Don't check result if we expected an error
3734+
}
3735+
3736+
if err != nil {
3737+
t.Errorf("getFastlyDomainAndConfigurationToActivationMap() unexpected error = %v", err)
3738+
return
3739+
}
3740+
3741+
// Check API call expectations
3742+
if tt.expectedPageRequests > 0 {
3743+
if actualPageRequests != tt.expectedPageRequests {
3744+
t.Errorf("getFastlyDomainAndConfigurationToActivationMap() made %d page requests, want %d", actualPageRequests, tt.expectedPageRequests)
3745+
}
3746+
}
3747+
3748+
// Check result structure
3749+
if result == nil {
3750+
t.Errorf("getFastlyDomainAndConfigurationToActivationMap() returned nil result")
3751+
return
3752+
}
3753+
3754+
// Verify the result matches expected map
3755+
if len(result) != len(tt.expectedMap) {
3756+
t.Errorf("getFastlyDomainAndConfigurationToActivationMap() returned map with %d domains, want %d", len(result), len(tt.expectedMap))
3757+
}
3758+
3759+
// Check each domain in the expected map
3760+
for expectedDomainID, expectedConfigs := range tt.expectedMap {
3761+
actualConfigs, domainExists := result[expectedDomainID]
3762+
if !domainExists {
3763+
t.Errorf("getFastlyDomainAndConfigurationToActivationMap() missing expected domain %q", expectedDomainID)
3764+
continue
3765+
}
3766+
3767+
if len(actualConfigs) != len(expectedConfigs) {
3768+
t.Errorf("getFastlyDomainAndConfigurationToActivationMap() domain %q has %d configs, want %d", expectedDomainID, len(actualConfigs), len(expectedConfigs))
3769+
}
3770+
3771+
// Check each configuration in the domain
3772+
for expectedConfigID, expectedActivation := range expectedConfigs {
3773+
actualActivation, configExists := actualConfigs[expectedConfigID]
3774+
if !configExists {
3775+
t.Errorf("getFastlyDomainAndConfigurationToActivationMap() domain %q missing expected config %q", expectedDomainID, expectedConfigID)
3776+
continue
3777+
}
3778+
3779+
// Verify activation details
3780+
if actualActivation.ID != expectedActivation.ID {
3781+
t.Errorf("getFastlyDomainAndConfigurationToActivationMap() domain %q config %q activation ID = %q, want %q", expectedDomainID, expectedConfigID, actualActivation.ID, expectedActivation.ID)
3782+
}
3783+
if actualActivation.Domain.ID != expectedActivation.Domain.ID {
3784+
t.Errorf("getFastlyDomainAndConfigurationToActivationMap() domain %q config %q activation domain ID = %q, want %q", expectedDomainID, expectedConfigID, actualActivation.Domain.ID, expectedActivation.Domain.ID)
3785+
}
3786+
if actualActivation.Configuration.ID != expectedActivation.Configuration.ID {
3787+
t.Errorf("getFastlyDomainAndConfigurationToActivationMap() domain %q config %q activation configuration ID = %q, want %q", expectedDomainID, expectedConfigID, actualActivation.Configuration.ID, expectedActivation.Configuration.ID)
3788+
}
3789+
}
3790+
}
3791+
3792+
// Check for unexpected domains in result
3793+
for actualDomainID := range result {
3794+
if _, expected := tt.expectedMap[actualDomainID]; !expected {
3795+
t.Errorf("getFastlyDomainAndConfigurationToActivationMap() unexpected domain %q in result", actualDomainID)
3796+
}
3797+
}
3798+
})
3799+
}
3800+
}

0 commit comments

Comments
 (0)