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 }