Skip to content

Commit 5dc9c34

Browse files
committed
Working tool, nearly all tests pass
1 parent 6d21717 commit 5dc9c34

132 files changed

Lines changed: 14810 additions & 2137 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net10.0</TargetFramework>
6+
<LangVersion>latest</LangVersion>
7+
<Nullable>enable</Nullable>
8+
<ImplicitUsings>enable</ImplicitUsings>
9+
<RootNamespace>IssueRunner</RootNamespace>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.1" />
14+
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.1" />
15+
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.1" />
16+
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.1" />
17+
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
18+
</ItemGroup>
19+
20+
<ItemGroup>
21+
<ProjectReference Include="..\IssueRunner.Core\IssueRunner.Core.csproj" />
22+
</ItemGroup>
23+
24+
</Project>
25+
26+
27+
28+
29+
Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ private static IServiceProvider ConfigureServices()
7979
services.AddSingleton<INuGetPackageVersionService, NuGetPackageVersionService>();
8080
services.AddSingleton<ITestExecutionService, TestExecutionService>();
8181
services.AddSingleton<IEnvironmentService, EnvironmentService>();
82+
services.AddSingleton<IMarkerService, MarkerService>();
8283
services.AddSingleton<ReportGeneratorService>();
8384

8485
services.AddTransient<SyncFromGitHubCommand>();
@@ -145,7 +146,7 @@ private static Command BuildRunCommand(IServiceProvider services)
145146
var scopeOption = new Option<TestScope>(
146147
"--scope",
147148
() => TestScope.All,
148-
"Test scope: All (default), New (untested), NewAndFailed (new or previously failed), RegressionOnly (closed issues), OpenOnly (open issues)");
149+
"Test scope: All (default), Regression (closed issues), Open (open issues)");
149150
var issuesOption = new Option<string?>(
150151
"--issues",
151152
"Comma-separated issue numbers");
@@ -162,10 +163,10 @@ private static Command BuildRunCommand(IServiceProvider services)
162163
var nunitOnlyOption = new Option<bool>(
163164
"--nunit-only",
164165
"Update only NUnit packages");
165-
var executionModeOption = new Option<ExecutionMode>(
166-
"--execution-mode",
167-
() => ExecutionMode.All,
168-
"Filter by execution method: All (default), Direct (dotnet test only), Custom (custom scripts only)");
166+
var testTypesOption = new Option<TestTypes>(
167+
"--test-types",
168+
() => TestTypes.All,
169+
"Filter by test types: All (default), Direct (dotnet test only), Custom (custom scripts only)");
169170
var verbosityOption = new Option<LogVerbosity>(
170171
"--verbosity",
171172
() => LogVerbosity.Normal,
@@ -184,7 +185,7 @@ private static Command BuildRunCommand(IServiceProvider services)
184185
runCommand.AddOption(skipNetFxOption);
185186
runCommand.AddOption(onlyNetFxOption);
186187
runCommand.AddOption(nunitOnlyOption);
187-
runCommand.AddOption(executionModeOption);
188+
runCommand.AddOption(testTypesOption);
188189
runCommand.AddOption(verbosityOption);
189190
runCommand.AddOption(feedOption);
190191
runCommand.AddOption(rerunFailedOption);
@@ -197,7 +198,7 @@ private static Command BuildRunCommand(IServiceProvider services)
197198
var skipNetFx = context.ParseResult.GetValueForOption(skipNetFxOption);
198199
var onlyNetFx = context.ParseResult.GetValueForOption(onlyNetFxOption);
199200
var nunitOnly = context.ParseResult.GetValueForOption(nunitOnlyOption);
200-
var executionMode = context.ParseResult.GetValueForOption(executionModeOption);
201+
var testTypes = context.ParseResult.GetValueForOption(testTypesOption);
201202
var verbosity = context.ParseResult.GetValueForOption(verbosityOption);
202203
var feed = context.ParseResult.GetValueForOption(feedOption);
203204
var rerunFailed = context.ParseResult.GetValueForOption(rerunFailedOption);
@@ -212,7 +213,7 @@ private static Command BuildRunCommand(IServiceProvider services)
212213
SkipNetFx = skipNetFx,
213214
OnlyNetFx = onlyNetFx,
214215
NUnitOnly = nunitOnly,
215-
ExecutionMode = executionMode,
216+
TestTypes = testTypes,
216217
Verbosity = verbosity,
217218
Feed = feed,
218219
RerunFailedTests = rerunFailed
@@ -234,19 +235,24 @@ private static Command BuildResetCommand(IServiceProvider services)
234235
var issuesOption = new Option<string?>(
235236
"--issues",
236237
"Comma-separated issue numbers (null means all)");
238+
var verbosityOption = new Option<LogVerbosity>(
239+
"--verbosity",
240+
() => LogVerbosity.Normal,
241+
"Logging verbosity (Normal or Verbose)");
237242

238243
resetCommand.AddOption(issuesOption);
244+
resetCommand.AddOption(verbosityOption);
239245

240-
resetCommand.SetHandler(async issues =>
246+
resetCommand.SetHandler(async (issues, verbosity) =>
241247
{
242248
var issueNumbers = string.IsNullOrEmpty(issues)
243249
? null
244250
: issues.Split(',').Select(int.Parse).ToList();
245251

246252
var env = services.GetRequiredService<IEnvironmentService>();
247253
var cmd = services.GetRequiredService<ResetPackagesCommand>();
248-
await cmd.ExecuteAsync(env.Root, issueNumbers, CancellationToken.None);
249-
}, issuesOption);
254+
await cmd.ExecuteAsync(env.Root, issueNumbers, verbosity, CancellationToken.None);
255+
}, issuesOption, verbosityOption);
250256

251257
return resetCommand;
252258
}
@@ -298,3 +304,4 @@ private static Command BuildMergeCommand(IServiceProvider services)
298304
return mergeCommand;
299305
}
300306
}
307+

Tools/IssueRunner.ComponentTests/GitHubApiServiceTests.cs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,84 @@ public async Task FetchMultipleIssues_ReturnsMetadataList()
106106
Console.WriteLine($"Fetched issue #{metadata.Number}: {metadata.Title}");
107107
}
108108
}
109+
110+
[Test]
111+
[Category("Integration")]
112+
public async Task FetchIssueMetadata_VerifiesApiAccess_ShowsAuthenticationStatus()
113+
{
114+
// Arrange
115+
var environment = Substitute.For<IEnvironmentService>();
116+
environment.RepositoryConfig.Returns(new RepositoryConfig("nunit", "nunit3-vs-adapter"));
117+
var service = new GitHubApiService(_httpClient!, environment, _logger!);
118+
119+
// Act - Try to fetch issue #1
120+
var metadata = await service.FetchIssueMetadataAsync(1, CancellationToken.None);
121+
var lastError = service.GetLastError();
122+
123+
// Assert - Check what happened
124+
if (metadata != null)
125+
{
126+
// Success - we have access
127+
Assert.Pass($"GitHub API access verified. Successfully fetched issue #{metadata.Number}: {metadata.Title}");
128+
}
129+
else if (!string.IsNullOrEmpty(lastError))
130+
{
131+
// Failed - show the error
132+
if (lastError.Contains("401") || lastError.Contains("Unauthorized") || lastError.Contains("Bad credentials"))
133+
{
134+
Assert.Fail($"GitHub API authentication failed: {lastError}. Set GITHUB_TOKEN environment variable with a valid token.");
135+
}
136+
else if (lastError.Contains("403") || lastError.Contains("Forbidden"))
137+
{
138+
Assert.Fail($"GitHub API access forbidden: {lastError}. Check token permissions or rate limits.");
139+
}
140+
else if (lastError.Contains("404") || lastError.Contains("Not Found"))
141+
{
142+
Assert.Fail($"Issue not found: {lastError}. This might indicate the repository or issue doesn't exist.");
143+
}
144+
else
145+
{
146+
Assert.Fail($"GitHub API access failed: {lastError}");
147+
}
148+
}
149+
else
150+
{
151+
Assert.Fail("GitHub API call returned null with no error message. This is unexpected.");
152+
}
153+
}
154+
155+
[Test]
156+
[Category("Integration")]
157+
public async Task FetchIssueMetadata_ChecksRateLimit_ShowsRemainingRequests()
158+
{
159+
// Arrange
160+
var environment = Substitute.For<IEnvironmentService>();
161+
environment.RepositoryConfig.Returns(new RepositoryConfig("nunit", "nunit3-vs-adapter"));
162+
var service = new GitHubApiService(_httpClient!, environment, _logger!);
163+
164+
// Act - Make a request to check rate limit headers
165+
var metadata = await service.FetchIssueMetadataAsync(1, CancellationToken.None);
166+
167+
// Note: We can't easily check rate limit headers from the service,
168+
// but we can check if we got a 403 with rate limit message
169+
var lastError = service.GetLastError();
170+
171+
if (!string.IsNullOrEmpty(lastError) && lastError.Contains("rate limit", StringComparison.OrdinalIgnoreCase))
172+
{
173+
Assert.Fail($"GitHub API rate limit exceeded: {lastError}");
174+
}
175+
else if (metadata != null)
176+
{
177+
Assert.Pass("GitHub API access successful. Rate limit check passed (no rate limit errors).");
178+
}
179+
else if (!string.IsNullOrEmpty(lastError))
180+
{
181+
// Other error, but not rate limit
182+
Assert.Inconclusive($"GitHub API call failed (not rate limit): {lastError}");
183+
}
184+
else
185+
{
186+
Assert.Inconclusive("Could not determine rate limit status.");
187+
}
188+
}
109189
}

Tools/IssueRunner.ComponentTests/IssueRunner.ComponentTests.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@
1414
<PackageReference Include="NUnit" Version="4.4.0" />
1515
<PackageReference Include="NUnit3TestAdapter" Version="6.0.0" />
1616
<PackageReference Include="NSubstitute" Version="5.3.0" />
17+
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.1" />
1718
</ItemGroup>
1819

1920
<ItemGroup>
20-
<ProjectReference Include="..\IssueRunner\IssueRunner.csproj" />
21+
<ProjectReference Include="..\IssueRunner.Core\IssueRunner.Core.csproj" />
2122
</ItemGroup>
2223

2324
<ItemGroup>

0 commit comments

Comments
 (0)