Skip to content

Commit 50260db

Browse files
committed
Fix cloud test assertions for ApiResponse wrapper and expected values
1 parent bcc78f9 commit 50260db

4 files changed

Lines changed: 45 additions & 36 deletions

File tree

cloud/tests/LrmCloud.Tests/Controllers/TranslationControllerTests.cs

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using LrmCloud.Api.Data;
55
using LrmCloud.Api.Services;
66
using LrmCloud.Api.Services.Translation;
7+
using LrmCloud.Shared.Api;
78
using LrmCloud.Shared.Configuration;
89
using LrmCloud.Shared.DTOs.Translation;
910
using LrmCloud.Shared.Entities;
@@ -162,8 +163,8 @@ public async Task GetProviders_ShouldReturnOkWithProviders()
162163

163164
// Assert
164165
var okResult = Assert.IsType<OkObjectResult>(result.Result);
165-
var providers = Assert.IsAssignableFrom<List<TranslationProviderDto>>(okResult.Value);
166-
Assert.NotEmpty(providers);
166+
var response = Assert.IsType<ApiResponse<List<TranslationProviderDto>>>(okResult.Value);
167+
Assert.NotEmpty(response.Data);
167168
}
168169

169170
[Fact]
@@ -178,9 +179,9 @@ public async Task GetProviders_ShouldRespectProjectContext()
178179

179180
// Assert
180181
var okResult = Assert.IsType<OkObjectResult>(result.Result);
181-
var providers = Assert.IsAssignableFrom<List<TranslationProviderDto>>(okResult.Value);
182+
var response = Assert.IsType<ApiResponse<List<TranslationProviderDto>>>(okResult.Value);
182183

183-
var google = providers.FirstOrDefault(p => p.Name == "google");
184+
var google = response.Data.FirstOrDefault(p => p.Name == "google");
184185
Assert.NotNull(google);
185186
Assert.True(google.IsConfigured);
186187
Assert.Equal("project", google.ApiKeySource);
@@ -198,8 +199,8 @@ public async Task GetUsage_ShouldReturnOkWithUsage()
198199

199200
// Assert
200201
var okResult = Assert.IsType<OkObjectResult>(result.Result);
201-
var usage = Assert.IsType<TranslationUsageDto>(okResult.Value);
202-
Assert.NotNull(usage.Plan);
202+
var response = Assert.IsType<ApiResponse<TranslationUsageDto>>(okResult.Value);
203+
Assert.NotNull(response.Data.Plan);
203204
}
204205

205206
// ============================================================
@@ -214,16 +215,16 @@ public async Task GetUsageByProvider_ShouldReturnOkWithList()
214215

215216
// Assert
216217
var okResult = Assert.IsType<OkObjectResult>(result.Result);
217-
var usage = Assert.IsAssignableFrom<List<ProviderUsageDto>>(okResult.Value);
218-
Assert.NotNull(usage);
218+
var response = Assert.IsType<ApiResponse<List<ProviderUsageDto>>>(okResult.Value);
219+
Assert.NotNull(response.Data);
219220
}
220221

221222
// ============================================================
222223
// TranslateKeys Tests
223224
// ============================================================
224225

225226
[Fact]
226-
public async Task TranslateKeys_ShouldReturnBadRequest_WhenProjectNotFound()
227+
public async Task TranslateKeys_ShouldReturnErrorInResponse_WhenProjectNotFound()
227228
{
228229
// Arrange
229230
var request = new TranslateRequestDto
@@ -234,10 +235,10 @@ public async Task TranslateKeys_ShouldReturnBadRequest_WhenProjectNotFound()
234235
// Act
235236
var result = await _controller.TranslateKeys(9999, request);
236237

237-
// Assert
238-
var badRequestResult = Assert.IsType<BadRequestObjectResult>(result.Result);
239-
var response = Assert.IsType<TranslateResponseDto>(badRequestResult.Value);
240-
Assert.Contains("Project not found", response.Errors);
238+
// Assert - Controller returns Success wrapper with errors inside
239+
var okResult = Assert.IsType<OkObjectResult>(result.Result);
240+
var apiResponse = Assert.IsType<ApiResponse<TranslateResponseDto>>(okResult.Value);
241+
Assert.Contains("Project not found", apiResponse.Data.Errors);
241242
}
242243

243244
[Fact]
@@ -301,7 +302,7 @@ public async Task SetUserApiKey_ShouldReturnOk_WhenSuccessful()
301302
var result = await _controller.SetUserApiKey(request);
302303

303304
// Assert
304-
Assert.IsType<OkObjectResult>(result);
305+
Assert.IsType<OkObjectResult>(result.Result);
305306

306307
// Verify key was saved
307308
var savedKey = await _db.UserApiKeys.FirstOrDefaultAsync(
@@ -321,7 +322,7 @@ public async Task SetUserApiKey_ShouldUpdateExistingKey()
321322
var result = await _controller.SetUserApiKey(request2);
322323

323324
// Assert
324-
Assert.IsType<OkObjectResult>(result);
325+
Assert.IsType<OkObjectResult>(result.Result);
325326

326327
var keys = await _db.UserApiKeys.Where(
327328
k => k.UserId == _testUser.Id && k.Provider == "google").ToListAsync();
@@ -342,7 +343,7 @@ public async Task RemoveUserApiKey_ShouldReturnOk_WhenKeyExists()
342343
var result = await _controller.RemoveUserApiKey("deepl");
343344

344345
// Assert
345-
Assert.IsType<OkObjectResult>(result);
346+
Assert.IsType<OkObjectResult>(result.Result);
346347

347348
var key = await _db.UserApiKeys.FirstOrDefaultAsync(
348349
k => k.UserId == _testUser.Id && k.Provider == "deepl");
@@ -356,7 +357,9 @@ public async Task RemoveUserApiKey_ShouldReturnNotFound_WhenKeyDoesNotExist()
356357
var result = await _controller.RemoveUserApiKey("nonexistent");
357358

358359
// Assert
359-
Assert.IsType<NotFoundObjectResult>(result);
360+
Assert.IsType<ObjectResult>(result.Result);
361+
var objectResult = (ObjectResult)result.Result!;
362+
Assert.Equal(404, objectResult.StatusCode);
360363
}
361364

362365
// ============================================================
@@ -378,7 +381,7 @@ public async Task SetProjectApiKey_ShouldReturnOk_WhenSuccessful()
378381
var result = await _controller.SetProjectApiKey(project.Id, request);
379382

380383
// Assert
381-
Assert.IsType<OkObjectResult>(result);
384+
Assert.IsType<OkObjectResult>(result.Result);
382385

383386
var savedKey = await _db.ProjectApiKeys.FirstOrDefaultAsync(
384387
k => k.ProjectId == project.Id && k.Provider == "google");
@@ -400,7 +403,7 @@ public async Task RemoveProjectApiKey_ShouldReturnOk_WhenKeyExists()
400403
var result = await _controller.RemoveProjectApiKey(project.Id, "deepl");
401404

402405
// Assert
403-
Assert.IsType<OkObjectResult>(result);
406+
Assert.IsType<OkObjectResult>(result.Result);
404407
}
405408

406409
[Fact]
@@ -413,7 +416,9 @@ public async Task RemoveProjectApiKey_ShouldReturnNotFound_WhenKeyDoesNotExist()
413416
var result = await _controller.RemoveProjectApiKey(project.Id, "nonexistent");
414417

415418
// Assert
416-
Assert.IsType<NotFoundObjectResult>(result);
419+
Assert.IsType<ObjectResult>(result.Result);
420+
var objectResult = (ObjectResult)result.Result!;
421+
Assert.Equal(404, objectResult.StatusCode);
417422
}
418423

419424
// ============================================================
@@ -435,7 +440,7 @@ public async Task SetOrganizationApiKey_ShouldReturnOk_WhenSuccessful()
435440
var result = await _controller.SetOrganizationApiKey(org.Id, request);
436441

437442
// Assert
438-
Assert.IsType<OkObjectResult>(result);
443+
Assert.IsType<OkObjectResult>(result.Result);
439444

440445
var savedKey = await _db.OrganizationApiKeys.FirstOrDefaultAsync(
441446
k => k.OrganizationId == org.Id && k.Provider == "openai");
@@ -457,7 +462,7 @@ public async Task RemoveOrganizationApiKey_ShouldReturnOk_WhenKeyExists()
457462
var result = await _controller.RemoveOrganizationApiKey(org.Id, "claude");
458463

459464
// Assert
460-
Assert.IsType<OkObjectResult>(result);
465+
Assert.IsType<OkObjectResult>(result.Result);
461466
}
462467

463468
[Fact]
@@ -470,7 +475,9 @@ public async Task RemoveOrganizationApiKey_ShouldReturnNotFound_WhenKeyDoesNotEx
470475
var result = await _controller.RemoveOrganizationApiKey(org.Id, "nonexistent");
471476

472477
// Assert
473-
Assert.IsType<NotFoundObjectResult>(result);
478+
Assert.IsType<ObjectResult>(result.Result);
479+
var objectResult = (ObjectResult)result.Result!;
480+
Assert.Equal(404, objectResult.StatusCode);
474481
}
475482

476483
// ============================================================
@@ -492,8 +499,8 @@ public async Task TestApiKey_ShouldReturnValid_ForProviderWithoutApiKeyRequireme
492499

493500
// Assert
494501
var okResult = Assert.IsType<OkObjectResult>(result.Result);
495-
var response = Assert.IsType<TestApiKeyResponse>(okResult.Value);
496-
Assert.True(response.IsValid);
502+
var apiResponse = Assert.IsType<ApiResponse<TestApiKeyResponse>>(okResult.Value);
503+
Assert.True(apiResponse.Data.IsValid);
497504
}
498505

499506
[Fact]
@@ -511,11 +518,11 @@ public async Task TestApiKey_ShouldReturnInvalid_ForBadApiKey()
511518

512519
// Assert
513520
var okResult = Assert.IsType<OkObjectResult>(result.Result);
514-
var response = Assert.IsType<TestApiKeyResponse>(okResult.Value);
521+
var apiResponse = Assert.IsType<ApiResponse<TestApiKeyResponse>>(okResult.Value);
515522

516523
// Should return invalid (not throw) for bad API key
517-
Assert.False(response.IsValid);
518-
Assert.NotNull(response.Error);
524+
Assert.False(apiResponse.Data.IsValid);
525+
Assert.NotNull(apiResponse.Data.Error);
519526
}
520527

521528
// ============================================================
@@ -547,9 +554,9 @@ await _controller.SetUserApiKey(new SetApiKeyRequest
547554

548555
// Assert
549556
var okResult = Assert.IsType<OkObjectResult>(result.Result);
550-
var providers = Assert.IsAssignableFrom<List<TranslationProviderDto>>(okResult.Value);
557+
var apiResponse = Assert.IsType<ApiResponse<List<TranslationProviderDto>>>(okResult.Value);
551558

552-
var google = providers.First(p => p.Name == "google");
559+
var google = apiResponse.Data.First(p => p.Name == "google");
553560
Assert.Equal("project", google.ApiKeySource); // Project should take precedence
554561
}
555562

@@ -579,9 +586,9 @@ await _controller.SetUserApiKey(new SetApiKeyRequest
579586

580587
// Assert
581588
var okResult = Assert.IsType<OkObjectResult>(result.Result);
582-
var providers = Assert.IsAssignableFrom<List<TranslationProviderDto>>(okResult.Value);
589+
var apiResponse = Assert.IsType<ApiResponse<List<TranslationProviderDto>>>(okResult.Value);
583590

584-
var deepl = providers.First(p => p.Name == "deepl");
591+
var deepl = apiResponse.Data.First(p => p.Name == "deepl");
585592
Assert.Equal("user", deepl.ApiKeySource); // User should take precedence over org
586593
}
587594
}

cloud/tests/LrmCloud.Tests/Services/ProjectServiceTests.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,8 @@ public async Task GetProjectAsync_CalculatesStatsCorrectly()
713713
Assert.NotNull(result);
714714
Assert.Equal(2, result.KeyCount);
715715
Assert.Equal(3, result.TranslationCount);
716-
Assert.Equal(100.0, result.CompletionPercentage); // All 3 translations have non-empty values
716+
// Completion = actual / expected = 3 / (2 keys × 2 languages) = 75%
717+
Assert.Equal(75.0, result.CompletionPercentage);
717718
}
718719

719720
[Fact]

cloud/tests/LrmCloud.Tests/Services/ResourceServiceTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,7 @@ public async Task ValidateProjectAsync_PendingTranslations_CreatesInfoIssues()
668668
var result = await _resourceService.ValidateProjectAsync(project.Id, user.Id);
669669

670670
// Assert
671-
Assert.Contains(result.Issues, i => i.Severity == "info" && i.Message.Contains("pending review"));
671+
Assert.Contains(result.Issues, i => i.Severity == "info" && i.Message.Contains("Pending review"));
672672
}
673673

674674
[Fact]

cloud/tests/LrmCloud.Tests/Services/Translation/CloudTranslationServiceTests.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,8 +468,9 @@ public async Task TranslateKeys_ShouldSkipKeysWithoutSourceValue()
468468
// Act
469469
var result = await _translationService.TranslateKeysAsync(project.Id, user.Id, request);
470470

471-
// Assert
472-
Assert.Equal(1, result.SkippedCount);
471+
// Assert - Keys without source values are silently skipped (not counted)
472+
// SkippedCount is only for keys with existing translations when OnlyMissing=true
473+
Assert.Equal(0, result.SkippedCount);
473474
Assert.Equal(0, result.TranslatedCount);
474475
}
475476

0 commit comments

Comments
 (0)