github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/pkg/plugins/yuks/yuks_test.go (about)

     1  /*
     2  Copyright 2017 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 yuks
    18  
    19  import (
    20  	"flag"
    21  	"fmt"
    22  	"net/http"
    23  	"net/http/httptest"
    24  	"strings"
    25  	"testing"
    26  
    27  	"github.com/sirupsen/logrus"
    28  
    29  	"sigs.k8s.io/prow/pkg/github"
    30  	"sigs.k8s.io/prow/pkg/github/fakegithub"
    31  )
    32  
    33  type fakeJoke string
    34  
    35  var human = flag.Bool("human", false, "Enable to run additional manual tests")
    36  
    37  func (j fakeJoke) readJoke() (string, error) {
    38  	return string(j), nil
    39  }
    40  
    41  func TestRealJoke(t *testing.T) {
    42  	if !*human {
    43  		t.Skip("Real jokes disabled for automation. Manual users can add --human")
    44  	}
    45  	if joke, err := jokeURL.readJoke(); err != nil {
    46  		t.Errorf("Could not read joke from %s: %v", jokeURL, err)
    47  	} else {
    48  		fmt.Println(joke)
    49  	}
    50  }
    51  
    52  // Medium integration test (depends on ability to open a TCP port)
    53  func TestJokesMedium(t *testing.T) {
    54  	j := "What do you get when you cross a joke with a rhetorical question?"
    55  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    56  		fmt.Fprintf(w, `{"joke": "%s"}`, j)
    57  	}))
    58  	defer ts.Close()
    59  	fc := fakegithub.NewFakeClient()
    60  
    61  	comment := "/joke"
    62  
    63  	e := &github.GenericCommentEvent{
    64  		Action:     github.GenericCommentActionCreated,
    65  		Body:       comment,
    66  		Number:     5,
    67  		IssueState: "open",
    68  	}
    69  	if err := handle(fc, logrus.WithField("plugin", pluginName), e, realJoke(ts.URL)); err != nil {
    70  		t.Errorf("didn't expect error: %v", err)
    71  		return
    72  	}
    73  	if len(fc.IssueComments[5]) != 1 {
    74  		t.Error("should have commented.")
    75  		return
    76  	}
    77  	if c := fc.IssueComments[5][0]; !strings.Contains(c.Body, j) {
    78  		t.Errorf("missing joke: %s from comment: %v", j, c)
    79  	}
    80  }
    81  
    82  // Small, unit tests
    83  func TestJokes(t *testing.T) {
    84  	var testcases = []struct {
    85  		name          string
    86  		action        github.GenericCommentEventAction
    87  		body          string
    88  		state         string
    89  		joke          fakeJoke
    90  		pr            bool
    91  		shouldComment bool
    92  		shouldError   bool
    93  	}{
    94  		{
    95  			name:          "ignore edited comment",
    96  			state:         "open",
    97  			action:        github.GenericCommentActionEdited,
    98  			body:          "/joke",
    99  			joke:          "this? that.",
   100  			shouldComment: false,
   101  			shouldError:   false,
   102  		},
   103  		{
   104  			name:          "leave joke on pr",
   105  			state:         "open",
   106  			action:        github.GenericCommentActionCreated,
   107  			body:          "/joke",
   108  			joke:          "this? that.",
   109  			pr:            true,
   110  			shouldComment: true,
   111  			shouldError:   false,
   112  		},
   113  		{
   114  			name:          "leave joke on issue",
   115  			state:         "open",
   116  			action:        github.GenericCommentActionCreated,
   117  			body:          "/joke",
   118  			joke:          "this? that.",
   119  			shouldComment: true,
   120  			shouldError:   false,
   121  		},
   122  		{
   123  			name:          "leave joke on issue, trailing space",
   124  			state:         "open",
   125  			action:        github.GenericCommentActionCreated,
   126  			body:          "/joke \r",
   127  			joke:          "this? that.",
   128  			shouldComment: true,
   129  			shouldError:   false,
   130  		},
   131  		{
   132  			name:          "reject bad joke chars",
   133  			state:         "open",
   134  			action:        github.GenericCommentActionCreated,
   135  			body:          "/joke",
   136  			joke:          "[hello](url)",
   137  			shouldComment: true,
   138  			shouldError:   false,
   139  		},
   140  		{
   141  			name:          "empty joke",
   142  			state:         "open",
   143  			action:        github.GenericCommentActionCreated,
   144  			body:          "/joke",
   145  			joke:          "",
   146  			shouldComment: false,
   147  			shouldError:   true,
   148  		},
   149  	}
   150  	for _, tc := range testcases {
   151  		fc := fakegithub.NewFakeClient()
   152  		e := &github.GenericCommentEvent{
   153  			Action:     tc.action,
   154  			Body:       tc.body,
   155  			Number:     5,
   156  			IssueState: tc.state,
   157  			IsPR:       tc.pr,
   158  		}
   159  		err := handle(fc, logrus.WithField("plugin", pluginName), e, tc.joke)
   160  		if !tc.shouldError && err != nil {
   161  			t.Errorf("For case %s, didn't expect error: %v", tc.name, err)
   162  			continue
   163  		} else if tc.shouldError && err == nil {
   164  			t.Errorf("For case %s, expected an error to occur", tc.name)
   165  			continue
   166  		}
   167  		if tc.shouldComment && len(fc.IssueComments[5]) != 1 {
   168  			t.Errorf("For case %s, should have commented.", tc.name)
   169  		} else if !tc.shouldComment && len(fc.IssueComments[5]) != 0 {
   170  			t.Errorf("For case %s, should not have commented.", tc.name)
   171  		}
   172  	}
   173  }
   174  
   175  // TestEscapeMarkdown tests escapeMarkdown
   176  func TestEscapeMarkdown(t *testing.T) {
   177  	var testcases = []struct {
   178  		name     string
   179  		joke     string
   180  		expected string
   181  	}{
   182  		{
   183  			name:     "simple characters, all allowed",
   184  			joke:     "this? that.",
   185  			expected: "this? that.",
   186  		},
   187  		{
   188  			name:     "markdown url",
   189  			joke:     "[hello](url)",
   190  			expected: "[hello](url)",
   191  		},
   192  		{
   193  			name:     "bold move",
   194  			joke:     "I made a <b>bold</b> move today: **move**",
   195  			expected: "I made a &#60;b&#62;bold&#60;&#47;b&#62; move today&#58; &#42;&#42;move&#42;&#42;",
   196  		},
   197  		{
   198  			name:     "helm symbol",
   199  			joke:     "⎈",
   200  			expected: "&#9096;",
   201  		},
   202  		{
   203  			name:     "xss attempt",
   204  			joke:     "<img src=404 onerror=alert('k8s')>",
   205  			expected: "&#60;img src&#61;404 onerror&#61;alert&#40;'k8s'&#41;&#62;",
   206  		},
   207  		{
   208  			name:     "empty joke",
   209  			joke:     "",
   210  			expected: "",
   211  		},
   212  		{
   213  			name:     "longcat is long",
   214  			joke:     "longcat is\n\n\n\n\n\n\nlong",
   215  			expected: "longcat is&#10;&#10;&#10;&#10;&#10;&#10;&#10;long",
   216  		},
   217  	}
   218  	for _, tc := range testcases {
   219  		output := escapeMarkdown(tc.joke)
   220  		if tc.expected != output {
   221  			t.Errorf("For case %s, expected `%s` got `%s`", tc.name, tc.expected, output)
   222  			continue
   223  		}
   224  	}
   225  }