test: add ContentServiceBaseTests skeleton for Phase 0
Adds unit test file for ContentServiceBase with documented test cases. Tests are commented out until ContentServiceBase is created in Phase 1: - 2 audit helper method tests - 2 scope provider access pattern tests - 2 logger injection tests - 1 repository access test 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,231 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Events;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Persistence.Repositories;
|
||||
using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Unit tests for ContentServiceBase (shared infrastructure for extracted services).
|
||||
/// These tests establish the expected contract for the base class before it's created.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// ContentServiceBase will be created in Phase 1. These tests validate the design requirements:
|
||||
/// - Audit helper method behavior
|
||||
/// - Scope provider access patterns
|
||||
/// - Logger injection patterns
|
||||
/// </remarks>
|
||||
[TestFixture]
|
||||
public class ContentServiceBaseTests
|
||||
{
|
||||
// Note: These tests will be uncommented when ContentServiceBase is created in Phase 1.
|
||||
// For now, they serve as documentation of the expected behavior.
|
||||
|
||||
/*
|
||||
private Mock<ICoreScopeProvider> _scopeProviderMock;
|
||||
private Mock<IAuditService> _auditServiceMock;
|
||||
private Mock<IEventMessagesFactory> _eventMessagesFactoryMock;
|
||||
private Mock<ILogger<TestContentService>> _loggerMock;
|
||||
private TestContentService _service;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_scopeProviderMock = new Mock<ICoreScopeProvider>();
|
||||
_auditServiceMock = new Mock<IAuditService>();
|
||||
_eventMessagesFactoryMock = new Mock<IEventMessagesFactory>();
|
||||
_loggerMock = new Mock<ILogger<TestContentService>>();
|
||||
|
||||
_eventMessagesFactoryMock.Setup(x => x.Get()).Returns(new EventMessages());
|
||||
|
||||
_service = new TestContentService(
|
||||
_scopeProviderMock.Object,
|
||||
_auditServiceMock.Object,
|
||||
_eventMessagesFactoryMock.Object,
|
||||
_loggerMock.Object);
|
||||
}
|
||||
|
||||
#region Audit Helper Method Tests
|
||||
|
||||
[Test]
|
||||
public void Audit_WithValidParameters_CreatesAuditEntry()
|
||||
{
|
||||
// Arrange
|
||||
var userId = 1;
|
||||
var objectId = 100;
|
||||
var message = "Test audit message";
|
||||
|
||||
// Act
|
||||
_service.TestAudit(AuditType.Save, userId, objectId, message);
|
||||
|
||||
// Assert
|
||||
_auditServiceMock.Verify(x => x.Write(
|
||||
userId,
|
||||
message,
|
||||
It.IsAny<string>(),
|
||||
objectId), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Audit_WithNullMessage_UsesDefaultMessage()
|
||||
{
|
||||
// Arrange
|
||||
var userId = 1;
|
||||
var objectId = 100;
|
||||
|
||||
// Act
|
||||
_service.TestAudit(AuditType.Save, userId, objectId, null);
|
||||
|
||||
// Assert
|
||||
_auditServiceMock.Verify(x => x.Write(
|
||||
userId,
|
||||
It.Is<string>(s => !string.IsNullOrEmpty(s)),
|
||||
It.IsAny<string>(),
|
||||
objectId), Times.Once);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Scope Provider Access Pattern Tests
|
||||
|
||||
[Test]
|
||||
public void CreateScope_ReturnsValidCoreScope()
|
||||
{
|
||||
// Arrange
|
||||
var scopeMock = new Mock<ICoreScope>();
|
||||
_scopeProviderMock.Setup(x => x.CreateCoreScope(
|
||||
It.IsAny<IsolationLevel>(),
|
||||
It.IsAny<RepositoryCacheMode>(),
|
||||
It.IsAny<IEventDispatcher>(),
|
||||
It.IsAny<IScopedNotificationPublisher>(),
|
||||
It.IsAny<bool>(),
|
||||
It.IsAny<bool>(),
|
||||
It.IsAny<bool>()))
|
||||
.Returns(scopeMock.Object);
|
||||
|
||||
// Act
|
||||
var scope = _service.TestCreateScope();
|
||||
|
||||
// Assert
|
||||
Assert.That(scope, Is.Not.Null);
|
||||
_scopeProviderMock.Verify(x => x.CreateCoreScope(
|
||||
It.IsAny<IsolationLevel>(),
|
||||
It.IsAny<RepositoryCacheMode>(),
|
||||
It.IsAny<IEventDispatcher>(),
|
||||
It.IsAny<IScopedNotificationPublisher>(),
|
||||
It.IsAny<bool>(),
|
||||
It.IsAny<bool>(),
|
||||
It.IsAny<bool>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateScope_WithAmbientScope_ReusesExisting()
|
||||
{
|
||||
// Arrange
|
||||
var ambientScopeMock = new Mock<ICoreScope>();
|
||||
_scopeProviderMock.SetupGet(x => x.AmbientScope).Returns(ambientScopeMock.Object);
|
||||
|
||||
// When ambient scope exists, CreateCoreScope should still be called
|
||||
// but the scope provider handles the nesting
|
||||
_scopeProviderMock.Setup(x => x.CreateCoreScope(
|
||||
It.IsAny<IsolationLevel>(),
|
||||
It.IsAny<RepositoryCacheMode>(),
|
||||
It.IsAny<IEventDispatcher>(),
|
||||
It.IsAny<IScopedNotificationPublisher>(),
|
||||
It.IsAny<bool>(),
|
||||
It.IsAny<bool>(),
|
||||
It.IsAny<bool>()))
|
||||
.Returns(ambientScopeMock.Object);
|
||||
|
||||
// Act
|
||||
var scope = _service.TestCreateScope();
|
||||
|
||||
// Assert - scope should be the ambient scope (or nested in it)
|
||||
Assert.That(scope, Is.Not.Null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Logger Injection Tests
|
||||
|
||||
[Test]
|
||||
public void Logger_IsInjectedCorrectly()
|
||||
{
|
||||
// Assert
|
||||
Assert.That(_service.TestLogger, Is.Not.Null);
|
||||
Assert.That(_service.TestLogger, Is.EqualTo(_loggerMock.Object));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Logger_UsesCorrectCategoryName()
|
||||
{
|
||||
// The logger should be typed to the concrete service class
|
||||
// This is verified by the generic type parameter
|
||||
Assert.That(_service.TestLogger, Is.InstanceOf<ILogger<TestContentService>>());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Repository Access Tests
|
||||
|
||||
[Test]
|
||||
public void DocumentRepository_IsAccessibleWithinScope()
|
||||
{
|
||||
// This test validates that the base class provides access to the document repository
|
||||
// The actual repository access pattern will be tested in integration tests
|
||||
Assert.Pass("Repository access validated in integration tests");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Test implementation of ContentServiceBase for unit testing.
|
||||
/// </summary>
|
||||
private class TestContentService : ContentServiceBase
|
||||
{
|
||||
public TestContentService(
|
||||
ICoreScopeProvider scopeProvider,
|
||||
IAuditService auditService,
|
||||
IEventMessagesFactory eventMessagesFactory,
|
||||
ILogger<TestContentService> logger)
|
||||
: base(scopeProvider, auditService, eventMessagesFactory, logger)
|
||||
{
|
||||
}
|
||||
|
||||
// Expose protected members for testing
|
||||
public void TestAudit(AuditType type, int userId, int objectId, string? message)
|
||||
=> Audit(type, userId, objectId, message);
|
||||
|
||||
public ICoreScope TestCreateScope() => ScopeProvider.CreateCoreScope();
|
||||
|
||||
public ILogger<TestContentService> TestLogger => Logger;
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// v1.3: Tracking test that fails when ContentServiceBase is created.
|
||||
/// When this test fails, uncomment all tests in this file and delete this placeholder.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ContentServiceBase_WhenCreated_UncommentTests()
|
||||
{
|
||||
// This tracking test uses reflection to detect when ContentServiceBase is created.
|
||||
// When you see this test fail, it means Phase 1 has created ContentServiceBase.
|
||||
// At that point:
|
||||
// 1. Uncomment all the tests in this file (the commented section above)
|
||||
// 2. Delete this tracking test
|
||||
// 3. Verify all tests pass
|
||||
|
||||
var type = Type.GetType("Umbraco.Cms.Infrastructure.Services.ContentServiceBase, Umbraco.Infrastructure");
|
||||
|
||||
Assert.That(type, Is.Null,
|
||||
"ContentServiceBase now exists! Uncomment all tests in this file and delete this tracking test.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user