Skip to content

Commit

Permalink
fix(connector): fix delete connector
Browse files Browse the repository at this point in the history
remove assigned offersubscriptions from connector when deleting the connector

Refs: CPLP-3105
  • Loading branch information
Phil91 committed Aug 3, 2023
1 parent 52fde75 commit 277fc1d
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ public async Task DeleteConnectorAsync(Guid connectorId)
{
var companyId = _identityService.IdentityData.CompanyId;
var connectorsRepository = _portalRepositories.GetInstance<IConnectorsRepository>();
var (isValidConnectorId, isProvidingOrHostCompany, selfDescriptionDocumentId, documentStatusId, connectorStatus) = await connectorsRepository.GetConnectorDeleteDataAsync(connectorId, companyId).ConfigureAwait(false);
var (isValidConnectorId, isProvidingOrHostCompany, selfDescriptionDocumentId, documentStatusId, connectorStatus, assignedOfferSubscriptions) = await connectorsRepository.GetConnectorDeleteDataAsync(connectorId, companyId).ConfigureAwait(false);

if (!isValidConnectorId)
{
Expand All @@ -287,26 +287,26 @@ public async Task DeleteConnectorAsync(Guid connectorId)
switch (connectorStatus)
{
case ConnectorStatusId.PENDING when selfDescriptionDocumentId == null:
await DeleteConnectorWithoutDocuments(connectorId, connectorsRepository);
await DeleteConnectorWithoutDocuments(connectorId, assignedOfferSubscriptions, connectorsRepository);
break;
case ConnectorStatusId.PENDING:
await DeleteConnectorWithDocuments(connectorId, selfDescriptionDocumentId.Value, connectorsRepository);
await DeleteConnectorWithDocuments(connectorId, assignedOfferSubscriptions, selfDescriptionDocumentId.Value, connectorsRepository);
break;
case ConnectorStatusId.ACTIVE when selfDescriptionDocumentId != null && documentStatusId != null:
await DeleteConnector(connectorId, selfDescriptionDocumentId.Value, documentStatusId.Value, connectorsRepository);
await DeleteConnector(connectorId, assignedOfferSubscriptions, selfDescriptionDocumentId.Value, documentStatusId.Value, connectorsRepository);
break;
default:
throw new ConflictException("Connector status does not match a deletion scenario. Deletion declined");
}
}

private async Task DeleteConnector(Guid connectorId, Guid selfDescriptionDocumentId, DocumentStatusId documentStatus, IConnectorsRepository connectorsRepository)
private async Task DeleteConnector(Guid connectorId, IEnumerable<Guid> assignedOfferSubscriptions, Guid selfDescriptionDocumentId, DocumentStatusId documentStatus, IConnectorsRepository connectorsRepository)
{
_portalRepositories.GetInstance<IDocumentRepository>().AttachAndModifyDocument(
selfDescriptionDocumentId,
a => { a.DocumentStatusId = documentStatus; },
a => { a.DocumentStatusId = DocumentStatusId.INACTIVE; });

RemoveConnectorAssignedOfferSubscriptions(connectorId, assignedOfferSubscriptions, connectorsRepository);
await DeleteUpdateConnectorDetail(connectorId, connectorsRepository);
}

Expand All @@ -320,19 +320,29 @@ private async Task DeleteUpdateConnectorDetail(Guid connectorId, IConnectorsRepo
await _portalRepositories.SaveAsync();
}

private async Task DeleteConnectorWithDocuments(Guid connectorId, Guid selfDescriptionDocumentId, IConnectorsRepository connectorsRepository)
private async Task DeleteConnectorWithDocuments(Guid connectorId, IEnumerable<Guid> assignedOfferSubscriptions, Guid selfDescriptionDocumentId, IConnectorsRepository connectorsRepository)
{
_portalRepositories.GetInstance<IDocumentRepository>().RemoveDocument(selfDescriptionDocumentId);
RemoveConnectorAssignedOfferSubscriptions(connectorId, assignedOfferSubscriptions, connectorsRepository);
connectorsRepository.DeleteConnector(connectorId);
await _portalRepositories.SaveAsync();
}

private async Task DeleteConnectorWithoutDocuments(Guid connectorId, IConnectorsRepository connectorsRepository)
private async Task DeleteConnectorWithoutDocuments(Guid connectorId, IEnumerable<Guid> assignedOfferSubscriptions, IConnectorsRepository connectorsRepository)
{
RemoveConnectorAssignedOfferSubscriptions(connectorId, assignedOfferSubscriptions, connectorsRepository);
connectorsRepository.DeleteConnector(connectorId);
await _portalRepositories.SaveAsync();
}

private static void RemoveConnectorAssignedOfferSubscriptions(Guid connectorId, IEnumerable<Guid> assignedOfferSubscriptions, IConnectorsRepository connectorsRepository)
{
if (assignedOfferSubscriptions.Any())
{
connectorsRepository.DeleteConnectorAssignedSubscriptions(connectorId, assignedOfferSubscriptions);
}
}

/// <inheritdoc/>
public IAsyncEnumerable<ConnectorEndPointData> GetCompanyConnectorEndPointAsync(IEnumerable<string> bpns)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,16 @@ public Connector AttachAndModifyConnector(Guid connectorId, Action<Connector>? i
.SingleOrDefaultAsync();

/// <inheritdoc />
public Task<(bool IsValidConnectorId, bool IsProvidingOrHostCompany, Guid? SelfDescriptionDocumentId, DocumentStatusId? DocumentStatusId, ConnectorStatusId ConnectorStatus)> GetConnectorDeleteDataAsync(Guid connectorId, Guid companyId) =>
public Task<(bool IsValidConnectorId, bool IsProvidingOrHostCompany, Guid? SelfDescriptionDocumentId, DocumentStatusId? DocumentStatusId, ConnectorStatusId ConnectorStatus, IEnumerable<Guid> AssignedOfferSubscriptions)> GetConnectorDeleteDataAsync(Guid connectorId, Guid companyId) =>
_context.Connectors
.Where(x => x.Id == connectorId)
.Select(connector => new ValueTuple<bool, bool, Guid?, DocumentStatusId?, ConnectorStatusId>(
.Select(connector => new ValueTuple<bool, bool, Guid?, DocumentStatusId?, ConnectorStatusId, IEnumerable<Guid>>(
true,
connector.ProviderId == companyId || connector.HostId == companyId,
connector.SelfDescriptionDocumentId,
connector.SelfDescriptionDocument!.DocumentStatusId,
connector.StatusId
connector.StatusId,
connector.ConnectorAssignedOfferSubscriptions.Select(x => x.OfferSubscriptionId)
)).SingleOrDefaultAsync();

/// <inheritdoc />
Expand All @@ -167,4 +168,8 @@ public void DeleteConnector(Guid connectorId) =>
/// <inheritdoc />
public ConnectorAssignedOfferSubscription CreateConnectorAssignedSubscriptions(Guid connectorId, Guid subscriptionId) =>
_context.ConnectorAssignedOfferSubscriptions.Add(new ConnectorAssignedOfferSubscription(connectorId, subscriptionId)).Entity;

/// <inheritdoc />
public void DeleteConnectorAssignedSubscriptions(Guid connectorId, IEnumerable<Guid> assignedOfferSubscriptions) =>
_context.ConnectorAssignedOfferSubscriptions.RemoveRange(assignedOfferSubscriptions.Select(x => new ConnectorAssignedOfferSubscription(connectorId, x)));
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public interface IConnectorsRepository
/// <param name="connectorId">Id of the connector</param>
/// <param name="companyId">Id of the company</param>
/// <returns>returns SelfDescriptionDocument Data/c></returns>
Task<(bool IsValidConnectorId, bool IsProvidingOrHostCompany, Guid? SelfDescriptionDocumentId, DocumentStatusId? DocumentStatusId, ConnectorStatusId ConnectorStatus)> GetConnectorDeleteDataAsync(Guid connectorId, Guid companyId);
Task<(bool IsValidConnectorId, bool IsProvidingOrHostCompany, Guid? SelfDescriptionDocumentId, DocumentStatusId? DocumentStatusId, ConnectorStatusId ConnectorStatus, IEnumerable<Guid> AssignedOfferSubscriptions)> GetConnectorDeleteDataAsync(Guid connectorId, Guid companyId);

/// <summary>
/// Gets the data required for the connector update
Expand All @@ -104,4 +104,6 @@ public interface IConnectorsRepository
void DeleteConnector(Guid connectorId);

ConnectorAssignedOfferSubscription CreateConnectorAssignedSubscriptions(Guid connectorId, Guid subscriptionId);

void DeleteConnectorAssignedSubscriptions(Guid connectorId, IEnumerable<Guid> assignedOfferSubscriptions);
}
Original file line number Diff line number Diff line change
Expand Up @@ -478,8 +478,9 @@ public async Task DeleteConnectorAsync_WithDocumentId_ExpectedCalls()
var connectorId = Guid.NewGuid();
var connector = new Connector(connectorId, null!, null!, null!);
var selfDescriptionDocumentId = Guid.NewGuid();
var assignedOfferSubscriptions = _fixture.CreateMany<Guid>(2);
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(A<Guid>._, _identity.CompanyId))
.Returns((true, true, selfDescriptionDocumentId, documentStatusId, ConnectorStatusId.ACTIVE));
.Returns((true, true, selfDescriptionDocumentId, documentStatusId, ConnectorStatusId.ACTIVE, assignedOfferSubscriptions));

A.CallTo(() => _documentRepository.AttachAndModifyDocument(A<Guid>._, A<Action<Document>>._, A<Action<Document>>._))
.Invokes((Guid docId, Action<Document>? initialize, Action<Document> modify)
Expand All @@ -504,6 +505,7 @@ public async Task DeleteConnectorAsync_WithDocumentId_ExpectedCalls()
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(connectorId, _identity.CompanyId)).MustHaveHappenedOnceExactly();
A.CallTo(() => _documentRepository.AttachAndModifyDocument(selfDescriptionDocumentId, A<Action<Document>>._, A<Action<Document>>._)).MustHaveHappenedOnceExactly();
A.CallTo(() => _connectorsRepository.AttachAndModifyConnector(connectorId, A<Action<Connector>>._, A<Action<Connector>>._)).MustHaveHappenedOnceExactly();
A.CallTo(() => _connectorsRepository.DeleteConnectorAssignedSubscriptions(connectorId, A<IEnumerable<Guid>>.That.Matches(x => x.Count() == 2))).MustHaveHappenedOnceExactly();
A.CallTo(() => _portalRepositories.SaveAsync()).MustHaveHappenedOnceExactly();
}

Expand All @@ -512,15 +514,17 @@ public async Task DeleteConnectorAsync_WithPendingAndWithoutDocumentId_ExpectedC
{
// Arrange
var connectorId = Guid.NewGuid();
var assignedOfferSubscriptions = _fixture.CreateMany<Guid>(2);
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(A<Guid>._, _identity.CompanyId))
.Returns((true, true, null, null, ConnectorStatusId.PENDING));
.Returns((true, true, null, null, ConnectorStatusId.PENDING, assignedOfferSubscriptions));

// Act
await _logic.DeleteConnectorAsync(connectorId).ConfigureAwait(false);

// Assert
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(connectorId, _identity.CompanyId)).MustHaveHappenedOnceExactly();
A.CallTo(() => _connectorsRepository.DeleteConnector(connectorId)).MustHaveHappenedOnceExactly();
A.CallTo(() => _connectorsRepository.DeleteConnectorAssignedSubscriptions(connectorId, A<IEnumerable<Guid>>.That.Matches(x => x.Count() == 2))).MustHaveHappenedOnceExactly();
A.CallTo(() => _portalRepositories.SaveAsync()).MustHaveHappenedOnceExactly();
}

Expand All @@ -531,8 +535,9 @@ public async Task DeleteConnectorAsync_WithPendingAndDocumentId_ExpectedCalls()
const DocumentStatusId documentStatusId = DocumentStatusId.LOCKED;
var connectorId = Guid.NewGuid();
var selfDescriptionDocumentId = Guid.NewGuid();
var assignedOfferSubscriptions = _fixture.CreateMany<Guid>(2);
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(A<Guid>._, _identity.CompanyId))
.Returns((true, true, selfDescriptionDocumentId, documentStatusId, ConnectorStatusId.PENDING));
.Returns((true, true, selfDescriptionDocumentId, documentStatusId, ConnectorStatusId.PENDING, assignedOfferSubscriptions));

// Act
await _logic.DeleteConnectorAsync(connectorId).ConfigureAwait(false);
Expand All @@ -541,6 +546,28 @@ public async Task DeleteConnectorAsync_WithPendingAndDocumentId_ExpectedCalls()
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(connectorId, _identity.CompanyId)).MustHaveHappenedOnceExactly();
A.CallTo(() => _documentRepository.RemoveDocument(selfDescriptionDocumentId)).MustHaveHappenedOnceExactly();
A.CallTo(() => _connectorsRepository.DeleteConnector(connectorId)).MustHaveHappenedOnceExactly();
A.CallTo(() => _connectorsRepository.DeleteConnectorAssignedSubscriptions(connectorId, A<IEnumerable<Guid>>.That.Matches(x => x.Count() == 2))).MustHaveHappenedOnceExactly();
A.CallTo(() => _portalRepositories.SaveAsync()).MustHaveHappenedOnceExactly();
}

[Fact]
public async Task DeleteConnectorAsync_WithoutAssignedOfferSubscriptions_ExpectedCalls()
{
// Arrange
const DocumentStatusId documentStatusId = DocumentStatusId.LOCKED;
var connectorId = Guid.NewGuid();
var selfDescriptionDocumentId = Guid.NewGuid();
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(A<Guid>._, _identity.CompanyId))
.Returns((true, true, selfDescriptionDocumentId, documentStatusId, ConnectorStatusId.PENDING, Enumerable.Empty<Guid>()));

// Act
await _logic.DeleteConnectorAsync(connectorId).ConfigureAwait(false);

// Assert
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(connectorId, _identity.CompanyId)).MustHaveHappenedOnceExactly();
A.CallTo(() => _documentRepository.RemoveDocument(selfDescriptionDocumentId)).MustHaveHappenedOnceExactly();
A.CallTo(() => _connectorsRepository.DeleteConnector(connectorId)).MustHaveHappenedOnceExactly();
A.CallTo(() => _connectorsRepository.DeleteConnectorAssignedSubscriptions(connectorId, A<IEnumerable<Guid>>._)).MustNotHaveHappened();
A.CallTo(() => _portalRepositories.SaveAsync()).MustHaveHappenedOnceExactly();
}

Expand All @@ -549,9 +576,8 @@ public async Task DeleteConnectorAsync_WithOutDocumentId_ExpectedCalls()
{
// Arrange
var connectorId = Guid.NewGuid();
var connector = new Connector(connectorId, null!, null!, null!);
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(connectorId, _identity.CompanyId))
.Returns((true, true, null, null, ConnectorStatusId.ACTIVE));
.Returns((true, true, null, null, ConnectorStatusId.ACTIVE, Enumerable.Empty<Guid>()));

// Act
async Task Act() => await _logic.DeleteConnectorAsync(connectorId).ConfigureAwait(false);
Expand All @@ -567,7 +593,7 @@ public async Task DeleteConnectorAsync_WithInactiveConnector_ThrowsConflictExcep
// Arrange
var connectorId = Guid.NewGuid();
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(connectorId, _identity.CompanyId))
.Returns((true, true, null, null, ConnectorStatusId.ACTIVE));
.Returns((true, true, null, null, ConnectorStatusId.ACTIVE, Enumerable.Empty<Guid>()));

// Act
async Task Act() => await _logic.DeleteConnectorAsync(connectorId).ConfigureAwait(false);
Expand All @@ -583,7 +609,7 @@ public async Task DeleteConnectorAsync_ThrowsNotFoundException()
// Arrange
var connectorId = Guid.NewGuid();
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(connectorId, _identity.CompanyId))
.Returns((false, false, null, null, ConnectorStatusId.ACTIVE));
.Returns((false, false, null, null, ConnectorStatusId.ACTIVE, Enumerable.Empty<Guid>()));

// Act
async Task Act() => await _logic.DeleteConnectorAsync(connectorId).ConfigureAwait(false);
Expand All @@ -599,7 +625,7 @@ public async Task DeleteConnectorAsync_ThrowsForbiddenException()
// Arrange
var connectorId = Guid.NewGuid();
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(connectorId, _identity.CompanyId))
.Returns((true, false, null, null, default));
.Returns((true, false, null, null, default, Enumerable.Empty<Guid>()));

// Act
async Task Act() => await _logic.DeleteConnectorAsync(connectorId).ConfigureAwait(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,29 @@ public async Task CreateConnectorAssignedSubscriptions_ExecutesExpected()

#endregion

#region DeleteConnector

[Fact]
public async Task DeleteConnectorAssignedSubscriptions_ExecutesExpected()
{
// Arrange
var (sut, context) = await CreateSut().ConfigureAwait(false);

// Act
sut.DeleteConnectorAssignedSubscriptions(new Guid("7e86a0b8-6903-496b-96d1-0ef508206833"), Enumerable.Repeat(new Guid("0b2ca541-206d-48ad-bc02-fb61fbcb5552"), 1));

// Assert
var changeTracker = context.ChangeTracker;
var changedEntries = changeTracker.Entries().ToList();
changeTracker.HasChanges().Should().BeTrue();
changedEntries.Should().NotBeEmpty();
changedEntries.Should().HaveCount(1);
var removedEntity = changedEntries.Single();
removedEntity.State.Should().Be(EntityState.Deleted);
}

#endregion

private async Task<(ConnectorsRepository, PortalDbContext)> CreateSut()
{
var context = await _dbTestDbFixture.GetPortalDbContext().ConfigureAwait(false);
Expand Down

0 comments on commit 277fc1d

Please sign in to comment.