Skip to content

DEV-14972: C# SDK storage-service compatibility unit tests#163

Open
sihrc wants to merge 1 commit intomasterfrom
dev-14972-csharp-sdk-storage-compat
Open

DEV-14972: C# SDK storage-service compatibility unit tests#163
sihrc wants to merge 1 commit intomasterfrom
dev-14972-csharp-sdk-storage-compat

Conversation

@sihrc
Copy link
Copy Markdown
Member

@sihrc sihrc commented Apr 12, 2026

Summary

  • Adds unit tests verifying the C# SDK is fully compatible with storage-service response shapes (the Rainbow replacement)
  • Audit result: no client patches neededDeserializeMetadata maps path/name/upload_type/size correctly via SnakeCaseNamingStrategy; UploadType.User deserializes correctly from "user" string; RetrieveBlob.Url extracts correct paths from indico-file:// URIs
  • Side finding: RetrieveBlob.Url produces a double-slash (//storage/...) due to Uri.ToString() adding a trailing slash — pre-existing behavior that nginx normalises; no fix needed for the migration

Test plan

  • RetrieveBlob_Url_ExtractsPath_FromIndicoFileSchemeUriindico-file:///storage/... path extraction
  • RetrieveBlob_Url_ExtractsPath_FromHttpUri — plain https URI passthrough
  • RetrieveBlob_Url_StripsSurroundingQuotes — GraphQL quoted URI handling
  • DeserializeMetadata_MapsPathAndName_FromStorageServiceResponse — field mapping
  • DeserializeMetadata_MapsSize_FromStorageServiceResponse — size field
  • DeserializeMetadata_MapsUploadType_UserStringToEnum"user"UploadType.User
  • DeserializeMetadata_HandlesMultipleFiles — multi-file batch
  • UploadAsync_NameMetaExtraction_ReadsNameFromStorageServiceItem — name/meta tuple pattern

All 8 tests pass. No network required.

Part of DEV-14699 storage-service migration epic.

🤖 Generated with Claude Code


Note

Low Risk
Low risk: adds new unit tests only, with no production code changes; risk is limited to potential test brittleness around URL normalization expectations.

Overview
Adds StorageCompatTests to validate the C# SDK’s storage integration against storage-service response shapes.

The tests cover RetrieveBlob.Url handling of indico-file:// and quoted URIs, StorageClient.DeserializeMetadata mapping of path/name/size/upload_type (including enum deserialization), and the UploadAsync JSON (Name, Meta) extraction pattern.

Reviewed by Cursor Bugbot for commit bb9e6b7. Bugbot is set up for automated code reviews on this repo. Configure here.

…ce response shapes

Audit confirms no client patches needed:
- DeserializeMetadata: path/name/upload_type/size map correctly from
  storage-service LegacyUploadResponseItem (SnakeCaseNamingStrategy +
  enum name matching handles "user" -> UploadType.User)
- RetrieveBlob.Url: indico-file:// path extraction works; double-slash
  is pre-existing behaviour nginx normalises
- JToken name/meta extraction pattern works on storage-service response

Tests use NUnit + FluentAssertions, no network required.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

Total Coverage: 0.00%

Coverage Report
FileBranchesFuncsLinesUncovered Lines
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\DataSets\DataSetClient.cs0%0%0%27, 27, 27, 27, 34, 34, 34, 34, 64, 64
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Exception\FileUploadException.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Exception\GraphQLException.cs0%0%0%28, 28
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Extensions\DataSets\DataSetAwaiter.cs0%0%0%27, 27
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Extensions\JobResultBuilders\JobResultBuilder.cs0%0%0%10, 10
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Extensions\JobResultBuilders\Submission\Exceptions\InvalidJobSubmissionResult.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Extensions\JobResultBuilders\Submission\Exceptions\InvalidUrlException.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Extensions\JobResultBuilders\Submission\UrlJobResult.cs0%0%0%15, 15, 20, 20, 27, 27
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Extensions\Jobs\JobAwaiter.cs0%0%0%37, 37, 42, 42
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Extensions\SubmissionResult\SubmissionResultAwaiter.cs0%0%0%26, 26, 33, 33, 33, 33, 40, 40, 42, 42
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Extensions\Workflows\WorkflowAwaiter.cs0%0%0%17, 17
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\GraphQLRequest\GraphQLRequestClient.cs0%0%0%24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 32, 32, 43, 43, 48, 48
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\IndicoClient.cs0%0%0%40, 40, 58, 58, 59, 59
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\IndicoClientExtensions.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Jobs\JobsClient.cs0%0%0%40, 40
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Models\ModelsClient.cs0%0%0%53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Ocr\OcrClient.cs0%0%0%38, 38
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Reviews\ReviewsClient.cs0%0%0%31, 31
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Storage\Blob.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Storage\FileParameter.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Storage\MultipartFormUpload.cs0%0%0%22, 22, 39, 39, 42, 42
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Storage\RetrieveBlob.cs0%0%0%24, 24, 51, 51, 69, 69
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Storage\StorageClient.cs0%0%0%106, 106, 109, 109, 72, 72, 78, 78
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Storage\UploadFile.cs0%0%0%29, 29, 35, 35, 40, 40, 59, 59, 82, 82, 85, 85
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Storage\UploadStream.cs0%0%0%30, 30, 49, 49, 52, 52
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Submissions\SubmissionsClient.cs0%0%0%102, 102, 104, 104, 105, 105, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 125, 125, 145, 145, 145, 145, 146, 146, 150, 150, 150, 150, 152, 152, 157, 157, 157, 157, 157, 157, 184, 184, 184, 184, 184, 184, 35, 35, 52, 52, 58, 58, 75, 75, 77, 77
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2\Workflows\WorkflowsClient.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\CommonModels\Pagination\HasCursor.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\CommonModels\Pagination\PageInfo.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\CommonModels\Predictions\Prediction.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Converters\CastingConverter.cs0%0%0%18, 18
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\DataSets\Models\DataSet.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\DataSets\Models\DataSetFull.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Extensions\SubmissionResult\Exceptions\WrongSubmissionStatusException.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Jobs\Exceptions\JobNotSuccessfulException.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Models\Models\Model.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Models\Models\ModelGroup.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Models\Models\ModelGroupBase.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Models\Models\PredictionJobResult.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Ocr\Models\ExtractionJobResult.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Reviews\Models\Review.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Reviews\Models\Review.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Storage\Models\FileMetadata.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Submissions\Models\AndFilter.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Submissions\Models\SubmissionFilter.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Submissions\Models\FilterConverter.cs0%0%0%17, 17, 21, 21, 25, 25, 29, 29, 33, 33, 35, 35, 37, 37, 46, 46, 50, 50, 54, 54, 62, 62, 72, 72, 80, 80
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Submissions\Models\OrFilter.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Submissions\Models\Submission.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Submissions\Models\Submission.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Submissions\Models\SubmissionFilter.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Submissions\Models\Submission.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Submissions\Models\Submission.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Submissions\Models\SubmissionFilter.cs100%0%0%
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Submissions\Models\Submission.cs0%0%0%241, 241, 242, 242, 280, 280, 280, 280, 280, 280, 280, 280, 280
D:\a\indico-client-csharp\indico-client-csharp\IndicoV2.Abstractions\Workflows\Models\Workflow.cs100%0%0%

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.

1 participant