package resources import ( "context" "encoding/base64" "os" "path/filepath" "testing" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) func TestValidatePackageSource(t *testing.T) { var diagnostics diag.Diagnostics ok := validatePackageSource(types.StringValue("code"), types.StringNull(), &diagnostics) if !ok || diagnostics.HasError() { t.Fatalf("expected valid source_dir-only config") } diagnostics = diag.Diagnostics{} ok = validatePackageSource(types.StringNull(), types.StringValue("main.zip"), &diagnostics) if !ok || diagnostics.HasError() { t.Fatalf("expected valid code_path-only config") } diagnostics = diag.Diagnostics{} ok = validatePackageSource(types.StringNull(), types.StringNull(), &diagnostics) if ok || !diagnostics.HasError() { t.Fatalf("expected invalid config when both values are empty") } } func TestLoadPackageLiteralFromSourceDir(t *testing.T) { tempDir := t.TempDir() mainPath := filepath.Join(tempDir, "main.py") content := []byte("def main():\n return 'ok'\n") if err := os.WriteFile(mainPath, content, 0o600); err != nil { t.Fatalf("write temp main.py: %v", err) } loaded, err := loadPackageLiteral(tempDir, "") if err != nil { t.Fatalf("loadPackageLiteral returned error: %v", err) } if string(loaded) != string(content) { t.Fatalf("unexpected loaded content") } } func TestPackageToUnstructured(t *testing.T) { input := packageResourceModel{ Name: types.StringValue("pkg-a"), Environment: types.StringValue("env-a"), } obj := packageToUnstructured(input, "default", []byte("print('hi')")) literal, found, err := unstructured.NestedString(obj.Object, "spec", "deployment", "literal") if err != nil || !found { t.Fatalf("deployment.literal not found") } decoded, err := base64.StdEncoding.DecodeString(literal) if err != nil { t.Fatalf("decode literal: %v", err) } if string(decoded) != "print('hi')" { t.Fatalf("unexpected decoded literal: %q", string(decoded)) } } func TestResolveNamespace(t *testing.T) { if got := resolveNamespace(types.StringValue("custom"), "default"); got != "custom" { t.Fatalf("unexpected namespace: %q", got) } if got := resolveNamespace(types.StringNull(), "default"); got != "default" { t.Fatalf("unexpected namespace fallback: %q", got) } } func TestUnstructuredToPackageModelSetsNullComputed(t *testing.T) { obj := &unstructured.Unstructured{Object: map[string]interface{}{ "apiVersion": "fission.io/v1", "kind": "Package", "metadata": map[string]interface{}{ "name": "pkg-a", "namespace": "default", }, "spec": map[string]interface{}{ "environment": map[string]interface{}{"name": "env-a"}, }, }} state := unstructuredToPackageModel(obj, packageResourceModel{}) if !state.BuildStatus.IsNull() { t.Fatalf("expected build_status to be null when status is absent") } if !state.BuildLog.IsNull() { t.Fatalf("expected build_log to be null when status is absent") } } func TestHTTPTriggerRoundTrip(t *testing.T) { ctx := context.Background() methods, diagnostics := types.ListValueFrom(ctx, types.StringType, []string{"GET", "POST"}) if diagnostics.HasError() { t.Fatalf("failed to create methods list") } model := httpTriggerResourceModel{ Name: types.StringValue("tr-a"), Function: types.StringValue("fn-a"), URL: types.StringValue("/hello"), Methods: methods, CreateIngress: types.BoolValue(true), Host: types.StringValue("fission.kube5s.ru"), } obj, err := httpTriggerToUnstructured(ctx, model, "default") if err != nil { t.Fatalf("httpTriggerToUnstructured error: %v", err) } state := unstructuredToHTTPTriggerModel(ctx, obj, model) if state.Name.ValueString() != "tr-a" { t.Fatalf("unexpected trigger name: %q", state.Name.ValueString()) } if state.Function.ValueString() != "fn-a" { t.Fatalf("unexpected function name: %q", state.Function.ValueString()) } if state.URL.ValueString() != "/hello" { t.Fatalf("unexpected url: %q", state.URL.ValueString()) } }