github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/pkg/spyglass/lenses/html/html_test.go (about)

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package html
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	"fmt"
    23  	"os"
    24  	"path/filepath"
    25  	"strings"
    26  	"testing"
    27  
    28  	"github.com/google/go-cmp/cmp"
    29  
    30  	"sigs.k8s.io/prow/pkg/config"
    31  	"sigs.k8s.io/prow/pkg/spyglass/api"
    32  )
    33  
    34  type FakeArtifact struct {
    35  	path    string
    36  	content []byte
    37  }
    38  
    39  func (fa *FakeArtifact) JobPath() string {
    40  	return fa.path
    41  }
    42  
    43  func (fa *FakeArtifact) Size() (int64, error) {
    44  	return int64(len(fa.content)), nil
    45  }
    46  
    47  func (fa *FakeArtifact) Metadata() (map[string]string, error) {
    48  	return nil, nil
    49  }
    50  
    51  func (fa *FakeArtifact) UpdateMetadata(map[string]string) error {
    52  	return nil
    53  }
    54  
    55  func (fa *FakeArtifact) CanonicalLink() string {
    56  	return fa.path
    57  }
    58  
    59  func (fa *FakeArtifact) ReadAt(b []byte, off int64) (int, error) {
    60  	r := bytes.NewReader(fa.content)
    61  	return r.ReadAt(b, off)
    62  }
    63  
    64  func (fa *FakeArtifact) ReadAll() ([]byte, error) {
    65  	return fa.content, nil
    66  }
    67  
    68  func (fa *FakeArtifact) ReadTail(n int64) ([]byte, error) {
    69  	return nil, nil
    70  }
    71  
    72  func (fa *FakeArtifact) UseContext(ctx context.Context) error {
    73  	return nil
    74  }
    75  
    76  func (fa *FakeArtifact) ReadAtMost(n int64) ([]byte, error) {
    77  	return nil, nil
    78  }
    79  
    80  func TestRenderBody(t *testing.T) {
    81  	testCases := []struct {
    82  		name      string
    83  		artifacts []FakeArtifact
    84  	}{
    85  		{
    86  			name: "Simple",
    87  			artifacts: []FakeArtifact{
    88  				{
    89  					path:    "https://s3.internal/bucket/file.html",
    90  					content: []byte(`<body>Hello world!</body>`),
    91  				},
    92  			},
    93  		},
    94  		{
    95  			name: "With quotes",
    96  			artifacts: []FakeArtifact{
    97  				{
    98  					path:    "https://s3.internal/bucket/file.html",
    99  					content: []byte(`<body>"Hello world!"</body>`),
   100  				},
   101  			},
   102  		},
   103  		{
   104  			name: "With title",
   105  			artifacts: []FakeArtifact{
   106  				{
   107  					path:    "https://s3.internal/bucket/file.html",
   108  					content: []byte(`<head><title>Custom Title</title><body>Hello world!</body>`),
   109  				},
   110  			},
   111  		},
   112  		{
   113  			name: "With description",
   114  			artifacts: []FakeArtifact{
   115  				{
   116  					path:    "https://s3.internal/bucket/file.html",
   117  					content: []byte(`<head><meta name="description" content="Loki is a log aggregation system"></head><body>Hello world!</body>`),
   118  				},
   119  			},
   120  		},
   121  		{
   122  			name: "With description and title",
   123  			artifacts: []FakeArtifact{
   124  				{
   125  					path:    "https://s3.internal/bucket/file.html",
   126  					content: []byte(`<head><meta name="description" content="Loki is a log aggregation system"><title>Custom tools</title><body></body>`),
   127  				},
   128  			},
   129  		},
   130  		{
   131  			name: "With multiple of same name",
   132  			artifacts: []FakeArtifact{
   133  				{
   134  					path:    "https://s3.internal/bucket/dir1/file.html",
   135  					content: []byte(`<head><title>File 1</title><body></body>`),
   136  				},
   137  				{
   138  					path:    "https://s3.internal/bucket/dir2/file.html",
   139  					content: []byte(`<head><title>File 2</title><body></body>`),
   140  				},
   141  			},
   142  		},
   143  	}
   144  
   145  	for _, tc := range testCases {
   146  		t.Run(tc.name, func(t *testing.T) {
   147  			for i := range tc.artifacts {
   148  				body := (Lens{}).Body([]api.Artifact{&tc.artifacts[i]}, ".", "", nil, config.Spyglass{})
   149  				fixtureName := filepath.Join("testdata", fmt.Sprintf("%s-%d.yaml", strings.ReplaceAll(t.Name(), "/", "_"), i))
   150  				if os.Getenv("UPDATE") != "" {
   151  					if err := os.WriteFile(fixtureName, []byte(body), 0644); err != nil {
   152  						t.Errorf("failed to update fixture: %v", err)
   153  					}
   154  				}
   155  				expectedRaw, err := os.ReadFile(fixtureName)
   156  				if err != nil {
   157  					t.Fatalf("failed to read fixture: %v", err)
   158  				}
   159  				expected := string(expectedRaw)
   160  				if diff := cmp.Diff(expected, body); diff != "" {
   161  					t.Errorf("expected doesn't match actual: \n%s\nIf this is expected, re-run the tests with the UPDATE env var set to update the fixture:\n\tUPDATE=true go test ./prow/spyglass/lenses/html/... -run TestRenderBody", diff)
   162  				}
   163  			}
   164  		})
   165  	}
   166  }