Skip to content

refactor(indexers): extract test logic into search providers#490

Open
lzinga wants to merge 4 commits intoListenarrs:canaryfrom
lzinga:refactor/indexer-test-providers
Open

refactor(indexers): extract test logic into search providers#490
lzinga wants to merge 4 commits intoListenarrs:canaryfrom
lzinga:refactor/indexer-test-providers

Conversation

@lzinga
Copy link
Copy Markdown
Contributor

@lzinga lzinga commented Apr 5, 2026

Summary

Extract indexer-specific test logic out of IndexersController and into the individual IIndexerSearchProvider implementations, so each provider owns both its search and connection-test behaviour. Closes #472.

Changes

Added

  • IndexerProviderBase and IndexerTestResult for shared test infrastructure
  • IndexerProviderTestAsyncTests covering all three provider types

Changed

  • Each IIndexerSearchProvider now owns its TestAsync implementation
  • IndexersController delegates to providers instead of containing inline test logic (~500 lines removed)
  • Existing tests updated for new constructor signature

Testing

  • New IndexerProviderTestAsyncTests covers success and failure paths for each provider type
  • Existing IndexersAuthTests, IndexersControllerTests, IndexersNewznabAuthTests, IndexersNewznabParsingTests, IndexersPersistedAuthTests, and IndexersControllerProwlarrImportTests updated and passing
  • Manual testing: verified "Test" button in Settings → Indexers works for Torznab, Newznab, MAM, and Internet Archive indexers

Notes

  • This is a pure refactor with no user-facing behaviour changes
  • Adding a new indexer type now only requires implementing a single IIndexerSearchProvider class (search + test in one place)
  • The IndexerProviderBase.TestAsync wrapper catches common HTTP/JSON/URI exceptions so individual providers only need to implement the happy path in ExecuteTestAsync

@lzinga lzinga marked this pull request as ready for review April 5, 2026 19:44
@T4g1
Copy link
Copy Markdown
Contributor

T4g1 commented Apr 7, 2026

@therobbiedavis This will conflict with #465 so it should be merged first, I can easilly solve those conflicts there

@lzinga For simplicity sake, could you maybe squash the commits ? Not sure what's the politic on that topic though, I usualy do one PR, one commit except for some specific cases, also, it may be easier to wait for Robbie's review too before squashing

…dation

- Move AdditionalSettings parsing to IndexerSettingsExtensions (Try-pattern)
- Add OutboundRequestSecurity validation to MAM TestAsync and SearchAsync
- Consolidate IA collection parsing to use shared extension
@lzinga
Copy link
Copy Markdown
Contributor Author

lzinga commented Apr 11, 2026

@lzinga For simplicity sake, could you maybe squash the commits ? Not sure what's the politic on that topic though, I usualy do one PR, one commit except for some specific cases, also, it may be easier to wait for Robbie's review too before squashing

The PR should have a squash and merge option when it gets approved.

Copy link
Copy Markdown
Collaborator

@therobbiedavis therobbiedavis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! Please review my review notes

{
private class StubHandler : HttpMessageHandler
{
private readonly HttpResponseMessage _response;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably use a factory for the httpresponsemessage so it gets a fresh instance in case there are multiple calls and the initial call has already been disposed.

{
return await ExecuteTestAsync(indexer);
}
catch (Exception ex) when (ex is HttpRequestException
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so broad and could throw errors for unrelated bugs. What about propagate those to other handlers and use a dedicated exception type for provider validation failures?


using (response)
{
response.EnsureSuccessStatusCode();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the IA provider has a logic inconsistency from the other two providers. This works, but the other providers return a IndexerTestResult.Failed() explicitly while this uses exceptions as a control flow. Can we refactor this to be more in line with the other providers for consistency?

if (string.IsNullOrWhiteSpace(indexer.ApiKey))
{
return IndexerTestResult.Failed(
"API key is required for Newznab/Torznab indexers",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Message is meant to be the user-facing summary; Error the technical detail. Passing the same string to both negates the distinction it was designed to carry. We should change this to something like:

    "API key required",
    "Newznab/Torznab indexers require an API key. Check your indexer settings");```

var provider = _indexerProviders.FirstOrDefault(p =>
string.Equals(p.IndexerType, indexer.Implementation, StringComparison.OrdinalIgnoreCase))
?? _indexerProviders.FirstOrDefault(p =>
string.Equals(p.IndexerType, "Torznab", StringComparison.OrdinalIgnoreCase));
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This causes a behavior regression for custom indexers where it now uses the torznabnewsnabsearchprovider instead of the testgenericindexer, however I think we should just remove the option for a custom indexer from the codebase which would make this a moot issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Separation of concerns: Indexers tests should be separated

3 participants