//go:build e2e && production package production import ( "crypto/tls" "fmt" "io" "net/http" "path/filepath" "testing" "time" "github.com/DeBrosOfficial/network/e2e" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // TestHTTPS_CertificateValid tests that HTTPS works with a valid certificate func TestHTTPS_CertificateValid(t *testing.T) { e2e.SkipIfLocal(t) env, err := e2e.LoadTestEnv() require.NoError(t, err, "Failed to load test environment") deploymentName := fmt.Sprintf("https-test-%d", time.Now().Unix()) tarballPath := filepath.Join("../../testdata/apps/react-app") deploymentID := e2e.CreateTestDeployment(t, env, deploymentName, tarballPath) defer func() { if !env.SkipCleanup { e2e.DeleteDeployment(t, env, deploymentID) } }() // Wait for deployment and certificate provisioning time.Sleep(5 * time.Second) domain := env.BuildDeploymentDomain(deploymentName) httpsURL := fmt.Sprintf("https://%s", domain) t.Run("HTTPS connection with certificate verification", func(t *testing.T) { // Create client that DOES verify certificates client := &http.Client{ Timeout: 30 * time.Second, Transport: &http.Transport{ TLSClientConfig: &tls.Config{ // Do NOT skip verification - we want to test real certs InsecureSkipVerify: false, }, }, } req, err := http.NewRequest("GET", httpsURL+"/", nil) require.NoError(t, err) resp, err := client.Do(req) if err != nil { // Certificate might not be ready yet, or domain might not resolve t.Logf("⚠ HTTPS request failed (this may be expected if certs are still provisioning): %v", err) t.Skip("HTTPS not available or certificate not ready") return } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) if resp.StatusCode != http.StatusOK { t.Logf("HTTPS returned %d (deployment may not be routed yet): %s", resp.StatusCode, string(body)) } // Check TLS connection state if resp.TLS != nil { t.Logf("✓ HTTPS works with valid certificate") t.Logf(" - Domain: %s", domain) t.Logf(" - TLS Version: %x", resp.TLS.Version) t.Logf(" - Cipher Suite: %x", resp.TLS.CipherSuite) if len(resp.TLS.PeerCertificates) > 0 { cert := resp.TLS.PeerCertificates[0] t.Logf(" - Certificate Subject: %s", cert.Subject) t.Logf(" - Certificate Issuer: %s", cert.Issuer) t.Logf(" - Valid Until: %s", cert.NotAfter) } } }) } // TestHTTPS_CertificateDetails tests certificate properties func TestHTTPS_CertificateDetails(t *testing.T) { e2e.SkipIfLocal(t) env, err := e2e.LoadTestEnv() require.NoError(t, err, "Failed to load test environment") t.Run("Base domain certificate", func(t *testing.T) { httpsURL := fmt.Sprintf("https://%s", env.BaseDomain) // Connect and get certificate info conn, err := tls.Dial("tcp", env.BaseDomain+":443", &tls.Config{ InsecureSkipVerify: true, // We just want to inspect the cert }) if err != nil { t.Logf("⚠ Could not connect to %s:443: %v", env.BaseDomain, err) t.Skip("HTTPS not available on base domain") return } defer conn.Close() certs := conn.ConnectionState().PeerCertificates require.NotEmpty(t, certs, "Should have certificates") cert := certs[0] t.Logf("Certificate for %s:", env.BaseDomain) t.Logf(" - Subject: %s", cert.Subject) t.Logf(" - DNS Names: %v", cert.DNSNames) t.Logf(" - Valid From: %s", cert.NotBefore) t.Logf(" - Valid Until: %s", cert.NotAfter) t.Logf(" - Issuer: %s", cert.Issuer) // Check that certificate covers our domain coversDomain := false for _, name := range cert.DNSNames { if name == env.BaseDomain || name == "*."+env.BaseDomain { coversDomain = true break } } assert.True(t, coversDomain, "Certificate should cover %s", env.BaseDomain) // Check certificate is not expired assert.True(t, time.Now().Before(cert.NotAfter), "Certificate should not be expired") assert.True(t, time.Now().After(cert.NotBefore), "Certificate should be valid now") // Make actual HTTPS request to verify it works client := &http.Client{ Timeout: 30 * time.Second, Transport: &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: false, }, }, } resp, err := client.Get(httpsURL) if err != nil { t.Logf("⚠ HTTPS request failed: %v", err) } else { resp.Body.Close() t.Logf("✓ HTTPS request succeeded with status %d", resp.StatusCode) } }) } // TestHTTPS_HTTPRedirect tests that HTTP requests are redirected to HTTPS func TestHTTPS_HTTPRedirect(t *testing.T) { e2e.SkipIfLocal(t) env, err := e2e.LoadTestEnv() require.NoError(t, err, "Failed to load test environment") t.Run("HTTP redirects to HTTPS", func(t *testing.T) { // Create client that doesn't follow redirects client := &http.Client{ Timeout: 30 * time.Second, CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse }, } httpURL := fmt.Sprintf("http://%s", env.BaseDomain) resp, err := client.Get(httpURL) if err != nil { t.Logf("⚠ HTTP request failed: %v", err) t.Skip("HTTP not available or redirects not configured") return } defer resp.Body.Close() // Check for redirect if resp.StatusCode >= 300 && resp.StatusCode < 400 { location := resp.Header.Get("Location") t.Logf("✓ HTTP redirects to: %s (status %d)", location, resp.StatusCode) assert.Contains(t, location, "https://", "Should redirect to HTTPS") } else if resp.StatusCode == http.StatusOK { // HTTP might just serve content directly in some configurations t.Logf("⚠ HTTP returned 200 instead of redirect (HTTPS redirect may not be configured)") } else { t.Logf("HTTP returned status %d", resp.StatusCode) } }) }