Skip to content
Snippets Groups Projects
cut_test.go 4.31 KiB
Newer Older
Volker Schukai's avatar
Volker Schukai committed
package html

import (
	"bytes"
	"github.com/andybalholm/cascadia"
	"gitlab.schukai.com/oss/bob/types"
	"golang.org/x/net/html"
	"gopkg.in/yaml.v3"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"
)

// Helper function to create a temporary file with content
func createTempFile(content string) (string, error) {
	tmpfile, err := ioutil.TempFile("", "example.*.html")
	if err != nil {
		return "", err
	}

	if _, err := tmpfile.Write([]byte(content)); err != nil {
		return "", err
	}

	if err := tmpfile.Close(); err != nil {
		return "", err
	}

	return tmpfile.Name(), nil
}

// TestCutHtml tests the CutHtml function
func TestCutHtml(t *testing.T) {
	// Create temporary directory
	tempDir, err := ioutil.TempDir("", "testcuthtml")
	if err != nil {
		t.Fatalf("Failed to create temp dir: %v", err)
	}
	defer os.RemoveAll(tempDir)

	// Create a temporary source HTML file
	sourceHTML := `<div><p class="content">Original content</p></div>`
	sourcePath := filepath.Join(tempDir, "source.html")
	if err := ioutil.WriteFile(sourcePath, []byte(sourceHTML), 0644); err != nil {
		t.Fatalf("Failed to write source HTML file: %v", err)
	}

	// Create a SnippetsSpecification in YAML format
	spec := types.SnippetsSpecification{
		Snippets: []types.Snippet{
			{
				Source:      sourcePath,
				Destination: sourcePath,
				Replacement: []types.ContentReplacement{
					{
						Selector: ".content",
						Content:  `<p class="content">Replaced content</p>`,
					},
				},
			},
		},
	}
	specBytes, err := yaml.Marshal(spec)
	if err != nil {
		t.Fatalf("Failed to marshal YAML: %v", err)
	}

	// Write the YAML to a temporary file
	specPath := filepath.Join(tempDir, "spec.yaml")
	if err := ioutil.WriteFile(specPath, specBytes, 0644); err != nil {
		t.Fatalf("Failed to write spec YAML file: %v", err)
	}

	// Run the CutHtml function
	if err := CutHtml(specPath); err != nil {
		t.Fatalf("CutHtml failed: %v", err)
	}

	// Verify the result
	modifiedHTML, err := ioutil.ReadFile(sourcePath)
	if err != nil {
		t.Fatalf("Failed to read modified HTML file: %v", err)
	}

	expectedHTML := `<div><p class="content">Replaced content</p></div>`
	if string(modifiedHTML) != expectedHTML {
		t.Errorf("Expected HTML to be '%v', but got '%v'", expectedHTML, string(modifiedHTML))
	}
}

// TestSetAttributes tests the setAttributes function
func TestSetAttributes(t *testing.T) {
	// Example HTML node
	rawHTML := `<div><p class="old-class">Hello</p></div>`
	node, _ := html.Parse(strings.NewReader(rawHTML))
	attrs := []types.Attributes{{Selector: "p", Name: "class", Value: "new-class"}}

	// Perform the attribute setting
	err := setAttributes(node, attrs)
	if err != nil {
		t.Errorf("setAttributes failed: %v", err)
	}

	// Check if the attribute was set correctly
	query, _ := cascadia.Compile("p")
	pNode := query.MatchFirst(node)
	if pNode == nil {
		t.Errorf("p node not found")
	} else if pNode.Attr[0].Val != "new-class" {
		t.Errorf("Attribute not set correctly, got: %s, want: new-class", pNode.Attr[0].Val)
	}
}

// TestRemoveAttribute tests the removeAttribute function
func TestRemoveAttribute(t *testing.T) {
	// Example attributes
	attrs := []html.Attribute{{Key: "class", Val: "old-class"}, {Key: "id", Val: "test-id"}}

	// Remove the 'class' attribute
	updatedAttrs := removeAttribute(attrs, "class")

	// Check if the 'class' attribute is removed
	for _, attr := range updatedAttrs {
		if attr.Key == "class" {
			t.Errorf("Attribute 'class' was not removed")
		}
	}
}

func TestReplaceNodes(t *testing.T) {
	// Example HTML node
	rawHTML := `<div><p class="target">Old Content</p><p class="untouched">Don't touch this</p></div>`
	node, _ := html.Parse(strings.NewReader(rawHTML))
	replacements := []types.ContentReplacement{
		{Selector: ".target", Content: "<p>New Content</p>"},
	}

	// Perform the replacement
	replacedNode, err := replaceNodes(node, replacements)
	if err != nil {
		t.Fatalf("replaceNodes failed: %v", err)
	}

	// Convert the node back to HTML for easy verification
	var buf bytes.Buffer
	html.Render(&buf, replacedNode)

	replacedHTML := buf.String()

	// Expected HTML after replacement
	expectedHTML := `<html><head></head><body><div><p>New Content</p><p class="untouched">Don't touch this</p></div></body></html>`

	// Verify the replacement
	if replacedHTML != expectedHTML {
		t.Errorf("Expected HTML to be '%v', but got '%v'", expectedHTML, replacedHTML)
	}
}