github.com/friedemannf/reviewdog@v0.14.0/doghouse/server/doghouse_test.go (about)

     1  package server
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"net/http"
     7  	"testing"
     8  
     9  	"github.com/google/go-cmp/cmp"
    10  	"github.com/google/go-github/v37/github"
    11  
    12  	"github.com/friedemannf/reviewdog/doghouse"
    13  	"github.com/friedemannf/reviewdog/filter"
    14  	"github.com/friedemannf/reviewdog/proto/rdf"
    15  )
    16  
    17  type fakeCheckerGitHubCli struct {
    18  	checkerGitHubClientInterface
    19  	FakeGetPullRequestDiff func(ctx context.Context, owner, repo string, number int) ([]byte, error)
    20  	FakeCreateCheckRun     func(ctx context.Context, owner, repo string, opt github.CreateCheckRunOptions) (*github.CheckRun, error)
    21  	FakeUpdateCheckRun     func(ctx context.Context, owner, repo string, checkID int64, opt github.UpdateCheckRunOptions) (*github.CheckRun, error)
    22  }
    23  
    24  func (f *fakeCheckerGitHubCli) GetPullRequestDiff(ctx context.Context, owner, repo string, number int) ([]byte, error) {
    25  	return f.FakeGetPullRequestDiff(ctx, owner, repo, number)
    26  }
    27  
    28  func (f *fakeCheckerGitHubCli) CreateCheckRun(ctx context.Context, owner, repo string, opt github.CreateCheckRunOptions) (*github.CheckRun, error) {
    29  	return f.FakeCreateCheckRun(ctx, owner, repo, opt)
    30  }
    31  
    32  func (f *fakeCheckerGitHubCli) UpdateCheckRun(ctx context.Context, owner, repo string, checkID int64, opt github.UpdateCheckRunOptions) (*github.CheckRun, error) {
    33  	return f.FakeUpdateCheckRun(ctx, owner, repo, checkID, opt)
    34  }
    35  
    36  const sampleDiff = `--- a/sample.old.txt	2016-10-13 05:09:35.820791185 +0900
    37  +++ b/sample.new.txt	2016-10-13 05:15:26.839245048 +0900
    38  @@ -1,3 +1,4 @@
    39   unchanged, contextual line
    40  -deleted line
    41  +added line
    42  +added line
    43   unchanged, contextual line
    44  --- a/nonewline.old.txt	2016-10-13 15:34:14.931778318 +0900
    45  +++ b/nonewline.new.txt	2016-10-13 15:34:14.868444672 +0900
    46  @@ -1,4 +1,4 @@
    47   " vim: nofixeol noendofline
    48   No newline at end of both the old and new file
    49  -a
    50  -a
    51  \ No newline at end of file
    52  +b
    53  +b
    54  \ No newline at end of file
    55  `
    56  
    57  func TestCheck_OK(t *testing.T) {
    58  	const (
    59  		name        = "haya14busa-linter"
    60  		owner       = "haya14busa"
    61  		repo        = "reviewdog"
    62  		prNum       = 14
    63  		sha         = "1414"
    64  		reportURL   = "http://example.com/report_url"
    65  		conclusion  = "neutral"
    66  		wantCheckID = 1414
    67  	)
    68  
    69  	req := &doghouse.CheckRequest{
    70  		Name:        name,
    71  		Owner:       owner,
    72  		Repo:        repo,
    73  		PullRequest: prNum,
    74  		SHA:         sha,
    75  		Annotations: []*doghouse.Annotation{
    76  			{
    77  				Diagnostic: &rdf.Diagnostic{
    78  					Message: "test message",
    79  					Location: &rdf.Location{
    80  						Path: "sample.new.txt",
    81  						Range: &rdf.Range{
    82  							Start: &rdf.Position{Line: 2, Column: 1},
    83  						},
    84  					},
    85  					OriginalOutput: "raw test message",
    86  				},
    87  			},
    88  			{
    89  				Diagnostic: &rdf.Diagnostic{
    90  					Message: "test message outside diff",
    91  					Location: &rdf.Location{
    92  						Path: "sample.new.txt",
    93  						Range: &rdf.Range{
    94  							Start: &rdf.Position{Line: 14},
    95  						},
    96  					},
    97  					OriginalOutput: "raw test message outside diff",
    98  				},
    99  			},
   100  			{
   101  				Diagnostic: &rdf.Diagnostic{
   102  					Message: "test multiline",
   103  					Location: &rdf.Location{
   104  						Path: "sample.new.txt",
   105  						Range: &rdf.Range{
   106  							Start: &rdf.Position{Line: 2},
   107  							End:   &rdf.Position{Line: 3},
   108  						},
   109  					},
   110  				},
   111  			},
   112  			{
   113  				Diagnostic: &rdf.Diagnostic{
   114  					Message: "test multiline with column",
   115  					Location: &rdf.Location{
   116  						Path: "sample.new.txt",
   117  						Range: &rdf.Range{
   118  							Start: &rdf.Position{Line: 2, Column: 1},
   119  							End:   &rdf.Position{Line: 3, Column: 5},
   120  						},
   121  					},
   122  				},
   123  			},
   124  			{
   125  				Diagnostic: &rdf.Diagnostic{
   126  					Message: "test range comment",
   127  					Location: &rdf.Location{
   128  						Path: "sample.new.txt",
   129  						Range: &rdf.Range{
   130  							Start: &rdf.Position{Line: 2, Column: 1},
   131  							End:   &rdf.Position{Line: 2, Column: 5},
   132  						},
   133  					},
   134  				},
   135  			},
   136  			{
   137  				Diagnostic: &rdf.Diagnostic{
   138  					Message:  "test severity override",
   139  					Severity: rdf.Severity_ERROR,
   140  					Location: &rdf.Location{
   141  						Path: "sample.new.txt",
   142  						Range: &rdf.Range{
   143  							Start: &rdf.Position{Line: 2},
   144  						},
   145  					},
   146  				},
   147  			},
   148  			{
   149  				Diagnostic: &rdf.Diagnostic{
   150  					Message: "source test",
   151  					Source: &rdf.Source{
   152  						Name: "awesome-linter",
   153  					},
   154  					Location: &rdf.Location{
   155  						Path: "sample.new.txt",
   156  						Range: &rdf.Range{
   157  							Start: &rdf.Position{Line: 2},
   158  						},
   159  					},
   160  				},
   161  			},
   162  			{
   163  				Diagnostic: &rdf.Diagnostic{
   164  					Message: "code test w/o URL",
   165  					Location: &rdf.Location{
   166  						Path:  "sample.new.txt",
   167  						Range: &rdf.Range{Start: &rdf.Position{Line: 2}},
   168  					},
   169  					Code: &rdf.Code{Value: "CODE14"},
   170  				},
   171  			},
   172  			{
   173  				Diagnostic: &rdf.Diagnostic{
   174  					Message: "code test w/ URL",
   175  					Location: &rdf.Location{
   176  						Path:  "sample.new.txt",
   177  						Range: &rdf.Range{Start: &rdf.Position{Line: 2}},
   178  					},
   179  					Code: &rdf.Code{Value: "CODE14", Url: "https://github.com/reviewdog#CODE14"},
   180  				},
   181  			},
   182  			{
   183  				Path:       "sample.new.txt",
   184  				Line:       2,
   185  				Message:    "request from old clients",
   186  				RawMessage: "raw message from old clients",
   187  			},
   188  		},
   189  		Level: "warning",
   190  	}
   191  
   192  	cli := &fakeCheckerGitHubCli{}
   193  	cli.FakeGetPullRequestDiff = func(ctx context.Context, owner, repo string, number int) ([]byte, error) {
   194  		return []byte(sampleDiff), nil
   195  	}
   196  	cli.FakeCreateCheckRun = func(ctx context.Context, owner, repo string, opt github.CreateCheckRunOptions) (*github.CheckRun, error) {
   197  		if opt.Name != name {
   198  			t.Errorf("CreateCheckRunOptions.Name = %q, want %q", opt.Name, name)
   199  		}
   200  		if opt.HeadSHA != sha {
   201  			t.Errorf("CreateCheckRunOptions.HeadSHA = %q, want %q", opt.HeadSHA, sha)
   202  		}
   203  		return &github.CheckRun{ID: github.Int64(wantCheckID)}, nil
   204  	}
   205  	cli.FakeUpdateCheckRun = func(ctx context.Context, owner, repo string, checkID int64, opt github.UpdateCheckRunOptions) (*github.CheckRun, error) {
   206  		if checkID != wantCheckID {
   207  			t.Errorf("UpdateCheckRun: checkID = %d, want %d", checkID, wantCheckID)
   208  		}
   209  		if opt.Name != name {
   210  			t.Errorf("UpdateCheckRunOptions.Name = %q, want %q", opt.Name, name)
   211  		}
   212  		annotations := opt.Output.Annotations
   213  		if len(annotations) == 0 {
   214  			if *opt.Conclusion != conclusion {
   215  				t.Errorf("UpdateCheckRunOptions.Conclusion = %q, want %q", *opt.Conclusion, conclusion)
   216  			}
   217  		} else {
   218  			wantAnnotations := []*github.CheckRunAnnotation{
   219  				{
   220  					Path:            github.String("sample.new.txt"),
   221  					StartLine:       github.Int(2),
   222  					EndLine:         github.Int(2),
   223  					AnnotationLevel: github.String("warning"),
   224  					Message:         github.String("test message"),
   225  					Title:           github.String("[haya14busa-linter] sample.new.txt#L2"),
   226  					RawDetails:      github.String("raw test message"),
   227  				},
   228  				{
   229  					Path:            github.String("sample.new.txt"),
   230  					StartLine:       github.Int(2),
   231  					EndLine:         github.Int(3),
   232  					AnnotationLevel: github.String("warning"),
   233  					Message:         github.String("test multiline"),
   234  					Title:           github.String("[haya14busa-linter] sample.new.txt#L2-L3"),
   235  				},
   236  				{
   237  					Path:            github.String("sample.new.txt"),
   238  					StartLine:       github.Int(2),
   239  					EndLine:         github.Int(3),
   240  					AnnotationLevel: github.String("warning"),
   241  					Message:         github.String("test multiline with column"),
   242  					Title:           github.String("[haya14busa-linter] sample.new.txt#L2-L3"),
   243  				},
   244  				{
   245  					Path:            github.String("sample.new.txt"),
   246  					StartLine:       github.Int(2),
   247  					EndLine:         github.Int(2),
   248  					StartColumn:     github.Int(1),
   249  					EndColumn:       github.Int(5),
   250  					AnnotationLevel: github.String("warning"),
   251  					Message:         github.String("test range comment"),
   252  					Title:           github.String("[haya14busa-linter] sample.new.txt#L2"),
   253  				},
   254  				{
   255  					Path:            github.String("sample.new.txt"),
   256  					StartLine:       github.Int(2),
   257  					EndLine:         github.Int(2),
   258  					AnnotationLevel: github.String("failure"),
   259  					Message:         github.String("test severity override"),
   260  					Title:           github.String("[haya14busa-linter] sample.new.txt#L2"),
   261  				},
   262  				{
   263  					Path:            github.String("sample.new.txt"),
   264  					StartLine:       github.Int(2),
   265  					EndLine:         github.Int(2),
   266  					AnnotationLevel: github.String("warning"),
   267  					Message:         github.String("source test"),
   268  					Title:           github.String("[awesome-linter] sample.new.txt#L2"),
   269  				},
   270  				{
   271  					Path:            github.String("sample.new.txt"),
   272  					StartLine:       github.Int(2),
   273  					EndLine:         github.Int(2),
   274  					AnnotationLevel: github.String("warning"),
   275  					Message:         github.String("code test w/o URL"),
   276  					Title:           github.String("[haya14busa-linter] sample.new.txt#L2 <CODE14>"),
   277  				},
   278  				{
   279  					Path:            github.String("sample.new.txt"),
   280  					StartLine:       github.Int(2),
   281  					EndLine:         github.Int(2),
   282  					AnnotationLevel: github.String("warning"),
   283  					Message:         github.String("code test w/ URL"),
   284  					Title:           github.String("[haya14busa-linter] sample.new.txt#L2 <CODE14>(https://github.com/reviewdog#CODE14)"),
   285  				},
   286  				{
   287  					Path:            github.String("sample.new.txt"),
   288  					StartLine:       github.Int(2),
   289  					EndLine:         github.Int(2),
   290  					AnnotationLevel: github.String("warning"),
   291  					Message:         github.String("request from old clients"),
   292  					Title:           github.String("[haya14busa-linter] sample.new.txt#L2"),
   293  					RawDetails:      github.String("raw message from old clients"),
   294  				},
   295  			}
   296  			if d := cmp.Diff(annotations, wantAnnotations); d != "" {
   297  				t.Errorf("Annotation diff found:\n%s", d)
   298  			}
   299  		}
   300  		return &github.CheckRun{HTMLURL: github.String(reportURL)}, nil
   301  	}
   302  	checker := &Checker{req: req, gh: cli}
   303  	res, err := checker.Check(context.Background())
   304  	if err != nil {
   305  		t.Fatal(err)
   306  	}
   307  
   308  	if res.ReportURL != reportURL {
   309  		t.Errorf("res.reportURL = %q, want %q", res.ReportURL, reportURL)
   310  	}
   311  }
   312  
   313  func testOutsideDiff(t *testing.T, outsideDiff bool, filterMode filter.Mode) {
   314  	const (
   315  		name        = "haya14busa-linter"
   316  		owner       = "haya14busa"
   317  		repo        = "reviewdog"
   318  		prNum       = 14
   319  		sha         = "1414"
   320  		reportURL   = "http://example.com/report_url"
   321  		conclusion  = "neutral"
   322  		wantCheckID = 1414
   323  	)
   324  
   325  	req := &doghouse.CheckRequest{
   326  		Name:        name,
   327  		Owner:       owner,
   328  		Repo:        repo,
   329  		PullRequest: prNum,
   330  		SHA:         sha,
   331  		Annotations: []*doghouse.Annotation{
   332  			{
   333  				Diagnostic: &rdf.Diagnostic{
   334  					Message: "test message",
   335  					Location: &rdf.Location{
   336  						Path: "sample.new.txt",
   337  						Range: &rdf.Range{
   338  							Start: &rdf.Position{Line: 2},
   339  						},
   340  					},
   341  					OriginalOutput: "raw test message",
   342  				},
   343  			},
   344  			{
   345  				Diagnostic: &rdf.Diagnostic{
   346  					Message: "test message outside diff",
   347  					Location: &rdf.Location{
   348  						Path: "sample.new.txt",
   349  						Range: &rdf.Range{
   350  							Start: &rdf.Position{Line: 14},
   351  						},
   352  					},
   353  					OriginalOutput: "raw test message outside diff",
   354  				},
   355  			},
   356  		},
   357  		Level:       "warning",
   358  		OutsideDiff: outsideDiff,
   359  		FilterMode:  filterMode,
   360  	}
   361  
   362  	cli := &fakeCheckerGitHubCli{}
   363  	cli.FakeGetPullRequestDiff = func(ctx context.Context, owner, repo string, number int) ([]byte, error) {
   364  		return []byte(sampleDiff), nil
   365  	}
   366  	cli.FakeCreateCheckRun = func(ctx context.Context, owner, repo string, opt github.CreateCheckRunOptions) (*github.CheckRun, error) {
   367  		return &github.CheckRun{ID: github.Int64(wantCheckID)}, nil
   368  	}
   369  	cli.FakeUpdateCheckRun = func(ctx context.Context, owner, repo string, checkID int64, opt github.UpdateCheckRunOptions) (*github.CheckRun, error) {
   370  		annotations := opt.Output.Annotations
   371  		if len(annotations) == 0 {
   372  			if *opt.Conclusion != conclusion {
   373  				t.Errorf("UpdateCheckRunOptions.Conclusion = %q, want %q", *opt.Conclusion, conclusion)
   374  			}
   375  		} else {
   376  			wantAnnotations := []*github.CheckRunAnnotation{
   377  				{
   378  					Path:            github.String("sample.new.txt"),
   379  					StartLine:       github.Int(2),
   380  					EndLine:         github.Int(2),
   381  					AnnotationLevel: github.String("warning"),
   382  					Message:         github.String("test message"),
   383  					Title:           github.String("[haya14busa-linter] sample.new.txt#L2"),
   384  					RawDetails:      github.String("raw test message"),
   385  				},
   386  				{
   387  					Path:            github.String("sample.new.txt"),
   388  					StartLine:       github.Int(14),
   389  					EndLine:         github.Int(14),
   390  					AnnotationLevel: github.String("warning"),
   391  					Message:         github.String("test message outside diff"),
   392  					Title:           github.String("[haya14busa-linter] sample.new.txt#L14"),
   393  					RawDetails:      github.String("raw test message outside diff"),
   394  				},
   395  			}
   396  			if d := cmp.Diff(annotations, wantAnnotations); d != "" {
   397  				t.Errorf("Annotation diff found:\n%s", d)
   398  			}
   399  		}
   400  		return &github.CheckRun{HTMLURL: github.String(reportURL)}, nil
   401  	}
   402  	checker := &Checker{req: req, gh: cli}
   403  	if _, err := checker.Check(context.Background()); err != nil {
   404  		t.Fatal(err)
   405  	}
   406  }
   407  
   408  func TestCheck_OK_deprecated_outsidediff(t *testing.T) {
   409  	t.Run("deprecated: outside_diff", func(t *testing.T) {
   410  		testOutsideDiff(t, true, filter.ModeDefault)
   411  	})
   412  	t.Run("filter-mode=NoFilter", func(t *testing.T) {
   413  		testOutsideDiff(t, false, filter.ModeNoFilter)
   414  	})
   415  }
   416  
   417  func TestCheck_OK_multiple_update_runs(t *testing.T) {
   418  	const (
   419  		name        = "haya14busa-linter"
   420  		owner       = "haya14busa"
   421  		repo        = "reviewdog"
   422  		prNum       = 14
   423  		sha         = "1414"
   424  		reportURL   = "http://example.com/report_url"
   425  		conclusion  = "neutral"
   426  		wantCheckID = 1414
   427  	)
   428  
   429  	req := &doghouse.CheckRequest{
   430  		Name:        name,
   431  		Owner:       owner,
   432  		Repo:        repo,
   433  		PullRequest: prNum,
   434  		SHA:         sha,
   435  		Level:       "warning",
   436  	}
   437  	for i := 0; i < 101; i++ {
   438  		req.Annotations = append(req.Annotations, &doghouse.Annotation{
   439  			Diagnostic: &rdf.Diagnostic{
   440  				Message: "test message",
   441  				Location: &rdf.Location{
   442  					Path: "sample.new.txt",
   443  					Range: &rdf.Range{
   444  						Start: &rdf.Position{Line: 2},
   445  					},
   446  				},
   447  				OriginalOutput: "raw test message",
   448  			},
   449  		})
   450  	}
   451  
   452  	cli := &fakeCheckerGitHubCli{}
   453  	cli.FakeGetPullRequestDiff = func(ctx context.Context, owner, repo string, number int) ([]byte, error) {
   454  		return []byte(sampleDiff), nil
   455  	}
   456  	cli.FakeCreateCheckRun = func(ctx context.Context, owner, repo string, opt github.CreateCheckRunOptions) (*github.CheckRun, error) {
   457  		if opt.Name != name {
   458  			t.Errorf("CreateCheckRunOptions.Name = %q, want %q", opt.Name, name)
   459  		}
   460  		if opt.HeadSHA != sha {
   461  			t.Errorf("CreateCheckRunOptions.HeadSHA = %q, want %q", opt.HeadSHA, sha)
   462  		}
   463  		return &github.CheckRun{ID: github.Int64(wantCheckID)}, nil
   464  	}
   465  	cli.FakeUpdateCheckRun = func(ctx context.Context, owner, repo string, checkID int64, opt github.UpdateCheckRunOptions) (*github.CheckRun, error) {
   466  		if checkID != wantCheckID {
   467  			t.Errorf("UpdateCheckRun: checkID = %d, want %d", checkID, wantCheckID)
   468  		}
   469  		annotations := opt.Output.Annotations
   470  		switch len(annotations) {
   471  		case 0:
   472  			if *opt.Conclusion != conclusion {
   473  				t.Errorf("UpdateCheckRunOptions.Conclusion = %q, want %q", *opt.Conclusion, conclusion)
   474  			}
   475  		case maxAnnotationsPerRequest, 1: // Expected
   476  		default:
   477  			t.Errorf("UpdateCheckRun: len(annotations) = %d, but it's unexpected", len(annotations))
   478  		}
   479  		return &github.CheckRun{HTMLURL: github.String(reportURL)}, nil
   480  	}
   481  	checker := &Checker{req: req, gh: cli}
   482  	if _, err := checker.Check(context.Background()); err != nil {
   483  		t.Fatal(err)
   484  	}
   485  }
   486  
   487  func TestCheck_OK_nonPullRequests(t *testing.T) {
   488  	const (
   489  		name        = "haya14busa-linter"
   490  		owner       = "haya14busa"
   491  		repo        = "reviewdog"
   492  		sha         = "1414"
   493  		reportURL   = "http://example.com/report_url"
   494  		conclusion  = "neutral"
   495  		wantCheckID = 1414
   496  	)
   497  
   498  	req := &doghouse.CheckRequest{
   499  		// Do not set PullRequest
   500  		Name:  name,
   501  		Owner: owner,
   502  		Repo:  repo,
   503  		SHA:   sha,
   504  		Annotations: []*doghouse.Annotation{
   505  			{
   506  				Diagnostic: &rdf.Diagnostic{
   507  					Message: "test message",
   508  					Location: &rdf.Location{
   509  						Path: "sample.new.txt",
   510  						Range: &rdf.Range{
   511  							Start: &rdf.Position{Line: 2},
   512  						},
   513  					},
   514  					OriginalOutput: "raw test message",
   515  				},
   516  			},
   517  			{
   518  				Diagnostic: &rdf.Diagnostic{
   519  					Message: "test message2",
   520  					Location: &rdf.Location{
   521  						Path: "sample.new.txt",
   522  						Range: &rdf.Range{
   523  							Start: &rdf.Position{Line: 14},
   524  						},
   525  					},
   526  					OriginalOutput: "raw test message2",
   527  				},
   528  			},
   529  		},
   530  		Level: "warning",
   531  	}
   532  
   533  	cli := &fakeCheckerGitHubCli{}
   534  	cli.FakeGetPullRequestDiff = func(ctx context.Context, owner, repo string, number int) ([]byte, error) {
   535  		t.Errorf("GetPullRequestDiff should not be called")
   536  		return nil, nil
   537  	}
   538  	cli.FakeCreateCheckRun = func(ctx context.Context, owner, repo string, opt github.CreateCheckRunOptions) (*github.CheckRun, error) {
   539  		return &github.CheckRun{ID: github.Int64(wantCheckID)}, nil
   540  	}
   541  	cli.FakeUpdateCheckRun = func(ctx context.Context, owner, repo string, checkID int64, opt github.UpdateCheckRunOptions) (*github.CheckRun, error) {
   542  		if checkID != wantCheckID {
   543  			t.Errorf("UpdateCheckRun: checkID = %d, want %d", checkID, wantCheckID)
   544  		}
   545  		annotations := opt.Output.Annotations
   546  		if len(annotations) == 0 {
   547  			if *opt.Conclusion != conclusion {
   548  				t.Errorf("UpdateCheckRunOptions.Conclusion = %q, want %q", *opt.Conclusion, conclusion)
   549  			}
   550  		} else {
   551  			wantAnnotations := []*github.CheckRunAnnotation{
   552  				{
   553  					Path:            github.String("sample.new.txt"),
   554  					StartLine:       github.Int(2),
   555  					EndLine:         github.Int(2),
   556  					AnnotationLevel: github.String("warning"),
   557  					Message:         github.String("test message"),
   558  					Title:           github.String("[haya14busa-linter] sample.new.txt#L2"),
   559  					RawDetails:      github.String("raw test message"),
   560  				},
   561  				{
   562  					Path:            github.String("sample.new.txt"),
   563  					StartLine:       github.Int(14),
   564  					EndLine:         github.Int(14),
   565  					AnnotationLevel: github.String("warning"),
   566  					Message:         github.String("test message2"),
   567  					Title:           github.String("[haya14busa-linter] sample.new.txt#L14"),
   568  					RawDetails:      github.String("raw test message2"),
   569  				},
   570  			}
   571  			if d := cmp.Diff(annotations, wantAnnotations); d != "" {
   572  				t.Errorf("Annotation diff found:\n%s", d)
   573  			}
   574  		}
   575  		return &github.CheckRun{HTMLURL: github.String(reportURL)}, nil
   576  	}
   577  	checker := &Checker{req: req, gh: cli}
   578  	res, err := checker.Check(context.Background())
   579  	if err != nil {
   580  		t.Fatal(err)
   581  	}
   582  
   583  	if res.ReportURL != reportURL {
   584  		t.Errorf("res.reportURL = %q, want %q", res.ReportURL, reportURL)
   585  	}
   586  }
   587  
   588  func TestCheck_fail_diff(t *testing.T) {
   589  	req := &doghouse.CheckRequest{PullRequest: 1}
   590  	cli := &fakeCheckerGitHubCli{}
   591  	cli.FakeGetPullRequestDiff = func(ctx context.Context, owner, repo string, number int) ([]byte, error) {
   592  		return nil, errors.New("test diff failure")
   593  	}
   594  	cli.FakeCreateCheckRun = func(ctx context.Context, owner, repo string, opt github.CreateCheckRunOptions) (*github.CheckRun, error) {
   595  		return &github.CheckRun{}, nil
   596  	}
   597  	checker := &Checker{req: req, gh: cli}
   598  
   599  	if _, err := checker.Check(context.Background()); err == nil {
   600  		t.Fatalf("got no error, want some error")
   601  	} else {
   602  		t.Log(err)
   603  	}
   604  }
   605  
   606  func TestCheck_fail_invalid_diff(t *testing.T) {
   607  	t.Skip("Parse invalid diff function somehow doesn't return error")
   608  	req := &doghouse.CheckRequest{PullRequest: 1}
   609  	cli := &fakeCheckerGitHubCli{}
   610  	cli.FakeGetPullRequestDiff = func(ctx context.Context, owner, repo string, number int) ([]byte, error) {
   611  		return []byte("invalid diff"), nil
   612  	}
   613  	cli.FakeCreateCheckRun = func(ctx context.Context, owner, repo string, opt github.CreateCheckRunOptions) (*github.CheckRun, error) {
   614  		return &github.CheckRun{}, nil
   615  	}
   616  	checker := &Checker{req: req, gh: cli}
   617  
   618  	if _, err := checker.Check(context.Background()); err == nil {
   619  		t.Fatalf("got no error, want some error")
   620  	} else {
   621  		t.Log(err)
   622  	}
   623  }
   624  
   625  func TestCheck_fail_check(t *testing.T) {
   626  	req := &doghouse.CheckRequest{PullRequest: 1}
   627  	cli := &fakeCheckerGitHubCli{}
   628  	cli.FakeGetPullRequestDiff = func(ctx context.Context, owner, repo string, number int) ([]byte, error) {
   629  		return []byte(sampleDiff), nil
   630  	}
   631  	cli.FakeCreateCheckRun = func(ctx context.Context, owner, repo string, opt github.CreateCheckRunOptions) (*github.CheckRun, error) {
   632  		return nil, errors.New("test check failure")
   633  	}
   634  	checker := &Checker{req: req, gh: cli}
   635  
   636  	if _, err := checker.Check(context.Background()); err == nil {
   637  		t.Fatalf("got no error, want some error")
   638  	} else {
   639  		t.Log(err)
   640  	}
   641  }
   642  
   643  func TestCheck_fail_check_with_403(t *testing.T) {
   644  	req := &doghouse.CheckRequest{PullRequest: 1}
   645  	cli := &fakeCheckerGitHubCli{}
   646  	cli.FakeGetPullRequestDiff = func(ctx context.Context, owner, repo string, number int) ([]byte, error) {
   647  		return []byte(sampleDiff), nil
   648  	}
   649  	cli.FakeCreateCheckRun = func(ctx context.Context, owner, repo string, opt github.CreateCheckRunOptions) (*github.CheckRun, error) {
   650  		return nil, &github.ErrorResponse{
   651  			Response: &http.Response{
   652  				StatusCode: http.StatusForbidden,
   653  			},
   654  		}
   655  	}
   656  	checker := &Checker{req: req, gh: cli}
   657  
   658  	resp, err := checker.Check(context.Background())
   659  	if err != nil {
   660  		t.Fatalf("got unexpected error: %v", err)
   661  	}
   662  	if resp.CheckedResults == nil {
   663  		t.Error("resp.CheckedResults should not be nil")
   664  	}
   665  }