github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/internal/featuredetection/feature_detection_test.go (about)

     1  package featuredetection
     2  
     3  import (
     4  	"net/http"
     5  	"testing"
     6  
     7  	"github.com/MakeNowJust/heredoc"
     8  	"github.com/ungtb10d/cli/v2/pkg/httpmock"
     9  	"github.com/stretchr/testify/assert"
    10  )
    11  
    12  func TestIssueFeatures(t *testing.T) {
    13  	tests := []struct {
    14  		name          string
    15  		hostname      string
    16  		queryResponse map[string]string
    17  		wantFeatures  IssueFeatures
    18  		wantErr       bool
    19  	}{
    20  		{
    21  			name:     "github.com",
    22  			hostname: "github.com",
    23  			wantFeatures: IssueFeatures{
    24  				StateReason: true,
    25  			},
    26  			wantErr: false,
    27  		},
    28  		{
    29  			name:     "GHE empty response",
    30  			hostname: "git.my.org",
    31  			queryResponse: map[string]string{
    32  				`query Issue_fields\b`: `{"data": {}}`,
    33  			},
    34  			wantFeatures: IssueFeatures{
    35  				StateReason: false,
    36  			},
    37  			wantErr: false,
    38  		},
    39  		{
    40  			name:     "GHE has state reason field",
    41  			hostname: "git.my.org",
    42  			queryResponse: map[string]string{
    43  				`query Issue_fields\b`: heredoc.Doc(`
    44  					{ "data": { "Issue": { "fields": [
    45  						{"name": "stateReason"}
    46  					] } } }
    47  				`),
    48  			},
    49  			wantFeatures: IssueFeatures{
    50  				StateReason: true,
    51  			},
    52  			wantErr: false,
    53  		},
    54  	}
    55  
    56  	for _, tt := range tests {
    57  		t.Run(tt.name, func(t *testing.T) {
    58  			reg := &httpmock.Registry{}
    59  			httpClient := &http.Client{}
    60  			httpmock.ReplaceTripper(httpClient, reg)
    61  			for query, resp := range tt.queryResponse {
    62  				reg.Register(httpmock.GraphQL(query), httpmock.StringResponse(resp))
    63  			}
    64  			detector := detector{host: tt.hostname, httpClient: httpClient}
    65  			gotFeatures, err := detector.IssueFeatures()
    66  			if tt.wantErr {
    67  				assert.Error(t, err)
    68  				return
    69  			}
    70  			assert.NoError(t, err)
    71  			assert.Equal(t, tt.wantFeatures, gotFeatures)
    72  		})
    73  	}
    74  }
    75  
    76  func TestPullRequestFeatures(t *testing.T) {
    77  	tests := []struct {
    78  		name          string
    79  		hostname      string
    80  		queryResponse map[string]string
    81  		wantFeatures  PullRequestFeatures
    82  		wantErr       bool
    83  	}{
    84  		{
    85  			name:     "github.com",
    86  			hostname: "github.com",
    87  			queryResponse: map[string]string{
    88  				`query PullRequest_fields\b`: heredoc.Doc(`
    89  					{ "data": { "PullRequest": { "fields": [
    90  						{"name": "isInMergeQueue"},
    91  						{"name": "isMergeQueueEnabled"}
    92  					] } } }
    93  				`),
    94  			},
    95  			wantFeatures: PullRequestFeatures{
    96  				ReviewDecision:       true,
    97  				StatusCheckRollup:    true,
    98  				BranchProtectionRule: true,
    99  				MergeQueue:           true,
   100  			},
   101  			wantErr: false,
   102  		},
   103  		{
   104  			name:     "github.com with no merge queue",
   105  			hostname: "github.com",
   106  			queryResponse: map[string]string{
   107  				`query PullRequest_fields\b`: heredoc.Doc(`
   108  					{ "data": { "PullRequest": { "fields": [
   109  					] } } }
   110  				`),
   111  			},
   112  			wantFeatures: PullRequestFeatures{
   113  				ReviewDecision:       true,
   114  				StatusCheckRollup:    true,
   115  				BranchProtectionRule: true,
   116  				MergeQueue:           false,
   117  			},
   118  			wantErr: false,
   119  		},
   120  		{
   121  			name:     "GHE",
   122  			hostname: "git.my.org",
   123  			queryResponse: map[string]string{
   124  				`query PullRequest_fields\b`: heredoc.Doc(`
   125  					{ "data": { "PullRequest": { "fields": [
   126  						{"name": "isInMergeQueue"},
   127  						{"name": "isMergeQueueEnabled"}
   128  					] } } }
   129  				`),
   130  			},
   131  			wantFeatures: PullRequestFeatures{
   132  				ReviewDecision:       true,
   133  				StatusCheckRollup:    true,
   134  				BranchProtectionRule: true,
   135  				MergeQueue:           true,
   136  			},
   137  			wantErr: false,
   138  		},
   139  	}
   140  	for _, tt := range tests {
   141  		t.Run(tt.name, func(t *testing.T) {
   142  			reg := &httpmock.Registry{}
   143  			httpClient := &http.Client{}
   144  			httpmock.ReplaceTripper(httpClient, reg)
   145  			for query, resp := range tt.queryResponse {
   146  				reg.Register(httpmock.GraphQL(query), httpmock.StringResponse(resp))
   147  			}
   148  			detector := detector{host: tt.hostname, httpClient: httpClient}
   149  			gotFeatures, err := detector.PullRequestFeatures()
   150  			if tt.wantErr {
   151  				assert.Error(t, err)
   152  				return
   153  			}
   154  			assert.NoError(t, err)
   155  			assert.Equal(t, tt.wantFeatures, gotFeatures)
   156  		})
   157  	}
   158  }
   159  
   160  func TestRepositoryFeatures(t *testing.T) {
   161  	tests := []struct {
   162  		name          string
   163  		hostname      string
   164  		queryResponse map[string]string
   165  		wantFeatures  RepositoryFeatures
   166  		wantErr       bool
   167  	}{
   168  		{
   169  			name:     "github.com",
   170  			hostname: "github.com",
   171  			wantFeatures: RepositoryFeatures{
   172  				IssueTemplateMutation:    true,
   173  				IssueTemplateQuery:       true,
   174  				PullRequestTemplateQuery: true,
   175  				VisibilityField:          true,
   176  				AutoMerge:                true,
   177  			},
   178  			wantErr: false,
   179  		},
   180  		{
   181  			name:     "GHE empty response",
   182  			hostname: "git.my.org",
   183  			queryResponse: map[string]string{
   184  				`query Repository_fields\b`: `{"data": {}}`,
   185  			},
   186  			wantFeatures: RepositoryFeatures{
   187  				IssueTemplateMutation:    true,
   188  				IssueTemplateQuery:       true,
   189  				PullRequestTemplateQuery: false,
   190  			},
   191  			wantErr: false,
   192  		},
   193  		{
   194  			name:     "GHE has pull request template query",
   195  			hostname: "git.my.org",
   196  			queryResponse: map[string]string{
   197  				`query Repository_fields\b`: heredoc.Doc(`
   198  					{ "data": { "Repository": { "fields": [
   199  						{"name": "pullRequestTemplates"}
   200  					] } } }
   201  				`),
   202  			},
   203  			wantFeatures: RepositoryFeatures{
   204  				IssueTemplateMutation:    true,
   205  				IssueTemplateQuery:       true,
   206  				PullRequestTemplateQuery: true,
   207  			},
   208  			wantErr: false,
   209  		},
   210  		{
   211  			name:     "GHE has visibility field",
   212  			hostname: "git.my.org",
   213  			queryResponse: map[string]string{
   214  				`query Repository_fields\b`: heredoc.Doc(`
   215  					{ "data": { "Repository": { "fields": [
   216  						{"name": "visibility"}
   217  					] } } }
   218  				`),
   219  			},
   220  			wantFeatures: RepositoryFeatures{
   221  				IssueTemplateMutation: true,
   222  				IssueTemplateQuery:    true,
   223  				VisibilityField:       true,
   224  			},
   225  			wantErr: false,
   226  		},
   227  		{
   228  			name:     "GHE has automerge field",
   229  			hostname: "git.my.org",
   230  			queryResponse: map[string]string{
   231  				`query Repository_fields\b`: heredoc.Doc(`
   232  					{ "data": { "Repository": { "fields": [
   233  						{"name": "autoMergeAllowed"}
   234  					] } } }
   235  				`),
   236  			},
   237  			wantFeatures: RepositoryFeatures{
   238  				IssueTemplateMutation: true,
   239  				IssueTemplateQuery:    true,
   240  				AutoMerge:             true,
   241  			},
   242  			wantErr: false,
   243  		},
   244  	}
   245  
   246  	for _, tt := range tests {
   247  		t.Run(tt.name, func(t *testing.T) {
   248  			reg := &httpmock.Registry{}
   249  			httpClient := &http.Client{}
   250  			httpmock.ReplaceTripper(httpClient, reg)
   251  			for query, resp := range tt.queryResponse {
   252  				reg.Register(httpmock.GraphQL(query), httpmock.StringResponse(resp))
   253  			}
   254  			detector := detector{host: tt.hostname, httpClient: httpClient}
   255  			gotFeatures, err := detector.RepositoryFeatures()
   256  			if tt.wantErr {
   257  				assert.Error(t, err)
   258  				return
   259  			}
   260  			assert.NoError(t, err)
   261  			assert.Equal(t, tt.wantFeatures, gotFeatures)
   262  		})
   263  	}
   264  }