github.com/sdqri/sequined@v0.0.0-20240421190656-fc6bf956f4d8/internal/hyperrenderer/webpage_test.go (about)

     1  package hyperrenderer_test
     2  
     3  import (
     4  	"bytes"
     5  	"flag"
     6  	"fmt"
     7  	"html/template"
     8  	"os"
     9  	"path"
    10  	"testing"
    11  
    12  	"github.com/goccy/go-graphviz"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  
    16  	hr "github.com/sdqri/sequined/internal/hyperrenderer"
    17  )
    18  
    19  func TestClone(t *testing.T) {
    20  	webpage := hr.NewWebpage(hr.WebpageTypeAuthority)
    21  
    22  	cloned := webpage.Clone(hr.WebpageTypeHub)
    23  
    24  	assert.Equal(t, webpage.AuthorityTmpl, cloned.AuthorityTmpl, "AuthorityTmpl changed after cloning")
    25  	assert.Equal(t, webpage.HubTmpl, cloned.HubTmpl, "HubTmpl changed after cloning")
    26  }
    27  
    28  func TestAddChild(t *testing.T) {
    29  	root := hr.NewWebpage(hr.WebpageTypeAuthority)
    30  
    31  	child := root.AddChild(hr.WebpageTypeHub)
    32  
    33  	assert.Len(t, root.Links, 1, "Parent page should have 1 link after adding child")
    34  	assert.Equal(t, child, root.Links[0], "Child page should be added to parent's links")
    35  
    36  	assert.Equal(t, root, child.Parent, "Child page's parent pointer should point to parent page")
    37  }
    38  
    39  //	func TestGetID(t *testing.T) {
    40  //		testCases := []struct {
    41  //			description string
    42  //			webpage     *Webpage
    43  //			expectedID  string
    44  //		}{
    45  //			{
    46  //				description: "Webpage with ID 1",
    47  //				webpage:     &Webpage{ID: 1},
    48  //				expectedID:  "1",
    49  //			},
    50  //			// Add more test cases as needed
    51  //		}
    52  //
    53  //		for _, tc := range testCases {
    54  //			t.Run(tc.description, func(t *testing.T) {
    55  //				assert.Equal(t, tc.expectedID, tc.webpage.GetID(), "Unexpected ID returned")
    56  //			})
    57  //		}
    58  //	}
    59  
    60  func TestHardCodedGetPath(t *testing.T) {
    61  	parentPage := &hr.Webpage{ID: 1, Path: "/", Type: hr.WebpageTypeAuthority}
    62  	childPage := &hr.Webpage{ID: 2, Path: "/2", Parent: parentPage, Type: hr.WebpageTypeHub}
    63  	grandChildPage := &hr.Webpage{ID: 3, Path: "/2/3", Parent: childPage, Type: hr.WebpageTypeHub}
    64  
    65  	testCases := []struct {
    66  		description  string
    67  		webpage      *hr.Webpage
    68  		expectedPath string
    69  	}{
    70  		{
    71  			description:  "Root Webpage",
    72  			webpage:      parentPage,
    73  			expectedPath: "/",
    74  		},
    75  		{
    76  			description:  "Child webpage",
    77  			webpage:      childPage,
    78  			expectedPath: "/2",
    79  		},
    80  		{
    81  			description:  "Grandchild webpage",
    82  			webpage:      grandChildPage,
    83  			expectedPath: "/2/3",
    84  		},
    85  	}
    86  
    87  	for _, tc := range testCases {
    88  		t.Run(tc.description, func(t *testing.T) {
    89  			assert.Equal(t, tc.expectedPath, tc.webpage.GetPath(), "Unexpected path returned")
    90  		})
    91  	}
    92  }
    93  
    94  func TestGetPathWithDefaultPathGenerator(t *testing.T) {
    95  	parentPage := hr.NewWebpage(hr.WebpageTypeHub)
    96  	childPage := parentPage.AddChild(hr.WebpageTypeHub)
    97  	grandChildPage := childPage.AddChild(hr.WebpageTypeHub)
    98  
    99  	testCases := []struct {
   100  		description  string
   101  		webpage      *hr.Webpage
   102  		expectedPath string
   103  	}{
   104  		{
   105  			description:  "Root Webpage",
   106  			webpage:      parentPage,
   107  			expectedPath: "/",
   108  		},
   109  		{
   110  			description:  "Child webpage",
   111  			webpage:      childPage,
   112  			expectedPath: fmt.Sprintf("/%s", childPage.GetID()),
   113  		},
   114  		{
   115  			description:  "Grandchild webpage",
   116  			webpage:      grandChildPage,
   117  			expectedPath: fmt.Sprintf("/%s/%s", childPage.GetID(), grandChildPage.GetID()),
   118  		},
   119  	}
   120  
   121  	for _, tc := range testCases {
   122  		t.Run(tc.description, func(t *testing.T) {
   123  			assert.Equal(t, tc.expectedPath, tc.webpage.GetPath(), "Unexpected path returned")
   124  		})
   125  	}
   126  }
   127  
   128  func TestRender(t *testing.T) {
   129  	authorityTemplate := `Authority Template: {{ .Node.ID }}`
   130  	hubTemplate := `Hub Template: {{ .Node.ID }}`
   131  	customTemplate := `Custom Template: {{ .Node.ID }}`
   132  
   133  	authorityTmpl, err := template.New("authority").Parse(authorityTemplate)
   134  	if err != nil {
   135  		t.Fatalf("Error parsing authority template: %v", err)
   136  	}
   137  	hubTmpl, err := template.New("hub").Parse(hubTemplate)
   138  	if err != nil {
   139  		t.Fatalf("Error parsing hub template: %v", err)
   140  	}
   141  	customTmpl, err := template.New("custom").Parse(customTemplate)
   142  	if err != nil {
   143  		t.Fatalf("Error parsing custom template: %v", err)
   144  	}
   145  
   146  	root := hr.NewWebpage(hr.WebpageTypeHub, hr.WithHubTemplate(hubTmpl), hr.WithAuthorityTemplate(authorityTmpl))
   147  	child := root.AddChild(hr.WebpageTypeAuthority)
   148  	grandChild := child.AddChild(hr.WebpageTypeAuthority, hr.WithCustomTemplate(customTmpl))
   149  
   150  	testCases := []struct {
   151  		name           string
   152  		webpage        *hr.Webpage
   153  		expectedOutput string
   154  	}{
   155  		{
   156  			name:           "Render root Page",
   157  			webpage:        root,
   158  			expectedOutput: "Hub Template: %s",
   159  		},
   160  		{
   161  			name:           "Render child Page",
   162  			webpage:        child,
   163  			expectedOutput: "Authority Template: %s",
   164  		},
   165  		{
   166  			name:           "Render grandChild Page",
   167  			webpage:        grandChild,
   168  			expectedOutput: "Custom Template: %s",
   169  		},
   170  	}
   171  
   172  	for _, tc := range testCases {
   173  		t.Run(tc.name, func(t *testing.T) {
   174  			var buf bytes.Buffer
   175  
   176  			err := tc.webpage.Render(&buf)
   177  			if err != nil {
   178  				t.Fatalf("Error rendering webpage: %v", err)
   179  			}
   180  
   181  			// Verify the output matches the expected output
   182  			assert.Equal(t, fmt.Sprintf(tc.expectedOutput, tc.webpage.GetID()), buf.String(), "Unexpected output")
   183  		})
   184  	}
   185  }
   186  
   187  func TestGetLinks(t *testing.T) {
   188  	rootPage := &hr.Webpage{ID: 1}
   189  	childPage2 := &hr.Webpage{ID: 2}
   190  	childPage3 := &hr.Webpage{ID: 3}
   191  	childPage4 := &hr.Webpage{ID: 4}
   192  
   193  	rootPage.AddLink(childPage2)
   194  	childPage2.AddLink(childPage3)
   195  	childPage2.AddLink(childPage4)
   196  
   197  	testCases := []struct {
   198  		description       string
   199  		webpage           *hr.Webpage
   200  		expectedLinkCount int
   201  	}{
   202  		{
   203  			description:       "No links",
   204  			webpage:           childPage4,
   205  			expectedLinkCount: 0,
   206  		},
   207  		{
   208  			description:       "One link",
   209  			webpage:           rootPage,
   210  			expectedLinkCount: 1,
   211  		},
   212  		{
   213  			description:       "two links",
   214  			webpage:           childPage2,
   215  			expectedLinkCount: 2,
   216  		},
   217  	}
   218  
   219  	for _, tc := range testCases {
   220  		t.Run(tc.description, func(t *testing.T) {
   221  			links := tc.webpage.GetLinks()
   222  
   223  			assert.Equal(t, tc.expectedLinkCount, len(links), "Unexpected number of links")
   224  		})
   225  	}
   226  }
   227  
   228  func TestAddLink(t *testing.T) {
   229  	testCases := []struct {
   230  		description         string
   231  		parentWebpageType   hr.WebpageType
   232  		childWebpageType    hr.WebpageType
   233  		expectParentToChild bool
   234  		expectChildInParent bool
   235  	}{
   236  		{
   237  			description:         "Authority to Hub",
   238  			parentWebpageType:   hr.WebpageTypeAuthority,
   239  			childWebpageType:    hr.WebpageTypeHub,
   240  			expectParentToChild: true,
   241  			expectChildInParent: true,
   242  		},
   243  		{
   244  			description:         "Hub to Authority",
   245  			parentWebpageType:   hr.WebpageTypeHub,
   246  			childWebpageType:    hr.WebpageTypeAuthority,
   247  			expectParentToChild: true,
   248  			expectChildInParent: true,
   249  		},
   250  		{
   251  			description:         "Authority to Authority",
   252  			parentWebpageType:   hr.WebpageTypeAuthority,
   253  			childWebpageType:    hr.WebpageTypeAuthority,
   254  			expectParentToChild: true,
   255  			expectChildInParent: true,
   256  		},
   257  		{
   258  			description:         "Hub to Hub",
   259  			parentWebpageType:   hr.WebpageTypeHub,
   260  			childWebpageType:    hr.WebpageTypeHub,
   261  			expectParentToChild: true,
   262  			expectChildInParent: true,
   263  		},
   264  	}
   265  
   266  	for _, tc := range testCases {
   267  		t.Run(tc.description, func(t *testing.T) {
   268  			parentPage := hr.NewWebpage(tc.parentWebpageType)
   269  			childPage := hr.NewWebpage(tc.childWebpageType)
   270  
   271  			parentPage.AddLink(childPage)
   272  
   273  			if tc.expectParentToChild {
   274  				assert.Equal(t, parentPage, childPage.Parent, "Incorrect parent assigned to child")
   275  			} else {
   276  				assert.Nil(t, childPage.Parent, "Child should not have a parent")
   277  			}
   278  
   279  			if tc.expectChildInParent {
   280  				assert.Contains(t, parentPage.Links, childPage, "Child not added to parent's links")
   281  			} else {
   282  				assert.NotContains(t, parentPage.Links, childPage, "Child should not be in parent's links")
   283  			}
   284  		})
   285  	}
   286  }
   287  
   288  var update = flag.Bool("update", false, "update golden files")
   289  
   290  func TestDrawGolden(t *testing.T) {
   291  	webpage := hr.Webpage{ID: 1}
   292  
   293  	wd, _ := os.Getwd()
   294  
   295  	var actual bytes.Buffer
   296  	err := webpage.Draw(graphviz.XDOT, &actual)
   297  	require.NoError(t, err, "Error generating DOT file")
   298  
   299  	goldenPath := path.Join(wd, "internal/hyperrenderer/test-fixtures", "draw.golden")
   300  	if *update {
   301  		os.WriteFile(goldenPath, actual.Bytes(), 0644)
   302  	}
   303  
   304  	expected, err := os.ReadFile(goldenPath)
   305  	require.NoError(t, err, "Error reading draw.golden file")
   306  
   307  	assert.Equal(t, string(expected), string(actual.Bytes()), "Generated output does not match golden output")
   308  }