Skip to content

Commit

Permalink
feat(Connector): deactivate tec-user on connector-deletion (#244)
Browse files Browse the repository at this point in the history
* feat: Deactivate Tech user before connector deletion
Refs: CPLP-3143
---------
Co-authored-by: Norbert Truchsess <[email protected]>
Reviewed-By: Norbert Truchsess <[email protected]>
  • Loading branch information
qxz2mqe authored Sep 5, 2023
1 parent abf1ef1 commit e426c9e
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,13 @@ public async Task DeleteConnectorAsync(Guid connectorId)
{
throw new ForbiddenException($"company {companyId} is neither provider nor host-company of connector {connectorId}");
}
if (result.ServiceAccountId.HasValue && result.UserStatusId != UserStatusId.INACTIVE)
{
_portalRepositories.GetInstance<IUserRepository>().AttachAndModifyIdentity(result.ServiceAccountId.Value, null, i =>
{
i.UserStatusId = UserStatusId.INACTIVE;
});
}

switch (result.ConnectorStatus)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ public record DeleteConnectorData(
Guid? SelfDescriptionDocumentId,
DocumentStatusId? DocumentStatusId,
ConnectorStatusId ConnectorStatus,
IEnumerable<ConnectorOfferSubscription> ConnectorOfferSubscriptions
IEnumerable<ConnectorOfferSubscription> ConnectorOfferSubscriptions,
UserStatusId? UserStatusId,
Guid? ServiceAccountId
);
public record ConnectorOfferSubscription(Guid AssignedOfferSubscriptionIds, OfferSubscriptionStatusId OfferSubscriptionStatus);
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,9 @@ public Connector AttachAndModifyConnector(Guid connectorId, Action<Connector>? i
connector.ConnectorAssignedOfferSubscriptions.Select(x => new ConnectorOfferSubscription(
x.OfferSubscriptionId,
x.OfferSubscription!.OfferSubscriptionStatusId
))
)),
connector.CompanyServiceAccount!.Identity!.UserStatusId,
connector.CompanyServiceAccountId
)).SingleOrDefaultAsync();

/// <inheritdoc />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ public async Task ProcessClearinghouseSelfDescription_WithExistingSelfDescriptio
#region DeleteConnector

[Fact]
public async Task DeleteConnectorAsync_WithDocumentId_ExpectedCalls()
public async Task DeleteConnectorAsync_WithDocumentId_AndActiveUser_ExpectedCalls()
{
// Arrange
const DocumentStatusId DocumentStatusId = DocumentStatusId.LOCKED;
Expand All @@ -481,8 +481,10 @@ public async Task DeleteConnectorAsync_WithDocumentId_ExpectedCalls()
new ConnectorOfferSubscription(_fixture.Create<Guid>(), OfferSubscriptionStatusId.PENDING),
new ConnectorOfferSubscription(_fixture.Create<Guid>(), OfferSubscriptionStatusId.PENDING),
};
var userId = Guid.NewGuid();
Identity? identity = null;
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(A<Guid>._, _identity.CompanyId))
.Returns(new DeleteConnectorData(true, selfDescriptionDocumentId, DocumentStatusId, ConnectorStatusId.ACTIVE, connectorOfferSubscriptions));
.Returns(new DeleteConnectorData(true, selfDescriptionDocumentId, DocumentStatusId, ConnectorStatusId.ACTIVE, connectorOfferSubscriptions, UserStatusId.ACTIVE, userId));

A.CallTo(() => _documentRepository.AttachAndModifyDocument(A<Guid>._, A<Action<Document>>._, A<Action<Document>>._))
.Invokes((Guid docId, Action<Document>? initialize, Action<Document> modify)
Expand All @@ -498,13 +500,66 @@ public async Task DeleteConnectorAsync_WithDocumentId_ExpectedCalls()
initialize?.Invoke(connector);
setOptionalFields.Invoke(connector);
});
A.CallTo(() => _userRepository.AttachAndModifyIdentity(A<Guid>._, A<Action<Identity>>._, A<Action<Identity>>._))
.Invokes((Guid id, Action<Identity>? initialize, Action<Identity> modify) =>
{
identity = new Identity(id, default, Guid.Empty, default, default);
initialize?.Invoke(identity);
modify.Invoke(identity);
});
// Act
await _logic.DeleteConnectorAsync(connectorId).ConfigureAwait(false);

// Assert
connector.StatusId.Should().Be(ConnectorStatusId.INACTIVE);
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(connectorId, _identity.CompanyId)).MustHaveHappenedOnceExactly();
A.CallTo(() => _userRepository.AttachAndModifyIdentity(userId, A<Action<Identity>>._, A<Action<Identity>>._)).MustHaveHappenedOnceExactly();
identity.Should().NotBeNull().And.Match<Identity>(x => x.Id == userId && x.UserStatusId == UserStatusId.INACTIVE);
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();
}

[Theory]
[InlineData(UserStatusId.INACTIVE, "0762ce2b-4842-41cd-a786-aa1bfe7061a3")]
[InlineData(null, null)]
public async Task DeleteConnectorAsync_WithDocumentId_WithInactiveOrNoUser_ExpectedCalls(UserStatusId? statusId, string? id)
{
// Arrange
const DocumentStatusId DocumentStatusId = DocumentStatusId.LOCKED;
var connectorId = Guid.NewGuid();
var connector = new Connector(connectorId, null!, null!, null!);
var selfDescriptionDocumentId = Guid.NewGuid();
var connectorOfferSubscriptions = new[] {
new ConnectorOfferSubscription(_fixture.Create<Guid>(), OfferSubscriptionStatusId.PENDING),
new ConnectorOfferSubscription(_fixture.Create<Guid>(), OfferSubscriptionStatusId.PENDING),
};
var userId = id == null ? (Guid?)null : new Guid(id);
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(A<Guid>._, _identity.CompanyId))
.Returns(new DeleteConnectorData(true, selfDescriptionDocumentId, DocumentStatusId, ConnectorStatusId.ACTIVE, connectorOfferSubscriptions, statusId, userId));

A.CallTo(() => _documentRepository.AttachAndModifyDocument(A<Guid>._, A<Action<Document>>._, A<Action<Document>>._))
.Invokes((Guid docId, Action<Document>? initialize, Action<Document> modify)
=>
{
var document = new Document(docId, null!, null!, null!, default, default, default, default);
initialize?.Invoke(document);
modify(document);
});
A.CallTo(() => _connectorsRepository.AttachAndModifyConnector(A<Guid>._, A<Action<Connector>>._, A<Action<Connector>>._))
.Invokes((Guid _, Action<Connector>? initialize, Action<Connector> setOptionalFields) =>
{
initialize?.Invoke(connector);
setOptionalFields.Invoke(connector);
});
// Act
await _logic.DeleteConnectorAsync(connectorId).ConfigureAwait(false);

// Assert
connector.StatusId.Should().Be(ConnectorStatusId.INACTIVE);
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(connectorId, _identity.CompanyId)).MustHaveHappenedOnceExactly();
A.CallTo(() => _userRepository.AttachAndModifyIdentity(A<Guid>._, A<Action<Identity>>._, A<Action<Identity>>._)).MustNotHaveHappened();
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();
Expand All @@ -521,7 +576,7 @@ public async Task DeleteConnectorAsync_WithPendingAndWithoutDocumentId_ExpectedC
new ConnectorOfferSubscription(_fixture.Create<Guid>(), OfferSubscriptionStatusId.PENDING),
};
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(A<Guid>._, _identity.CompanyId))
.Returns(new DeleteConnectorData(true, null, null, ConnectorStatusId.PENDING, connectorOfferSubscriptions));
.Returns(new DeleteConnectorData(true, null, null, ConnectorStatusId.PENDING, connectorOfferSubscriptions, UserStatusId.ACTIVE, Guid.NewGuid()));

// Act
await _logic.DeleteConnectorAsync(connectorId).ConfigureAwait(false);
Expand All @@ -545,7 +600,7 @@ public async Task DeleteConnectorAsync_WithPendingAndDocumentId_ExpectedCalls()
new ConnectorOfferSubscription(_fixture.Create<Guid>(), OfferSubscriptionStatusId.PENDING),
};
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(A<Guid>._, _identity.CompanyId))
.Returns(new DeleteConnectorData(true, selfDescriptionDocumentId, DocumentStatusId, ConnectorStatusId.PENDING, connectorOfferSubscriptions));
.Returns(new DeleteConnectorData(true, selfDescriptionDocumentId, DocumentStatusId, ConnectorStatusId.PENDING, connectorOfferSubscriptions, UserStatusId.ACTIVE, Guid.NewGuid()));

// Act
await _logic.DeleteConnectorAsync(connectorId).ConfigureAwait(false);
Expand All @@ -566,7 +621,7 @@ public async Task DeleteConnectorAsync_WithoutAssignedOfferSubscriptions_Expecte
var connectorId = Guid.NewGuid();
var selfDescriptionDocumentId = Guid.NewGuid();
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(A<Guid>._, _identity.CompanyId))
.Returns(new DeleteConnectorData(true, selfDescriptionDocumentId, DocumentStatusId, ConnectorStatusId.PENDING, Enumerable.Empty<ConnectorOfferSubscription>()));
.Returns(new DeleteConnectorData(true, selfDescriptionDocumentId, DocumentStatusId, ConnectorStatusId.PENDING, Enumerable.Empty<ConnectorOfferSubscription>(), UserStatusId.ACTIVE, Guid.NewGuid()));

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

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

// Act
async Task Act() => await _logic.DeleteConnectorAsync(connectorId).ConfigureAwait(false);
Expand Down Expand Up @@ -633,7 +688,7 @@ public async Task DeleteConnectorAsync_ThrowsForbiddenException()
// Arrange
var connectorId = Guid.NewGuid();
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(connectorId, _identity.CompanyId))
.Returns(new DeleteConnectorData(false, null, null, default, Enumerable.Empty<ConnectorOfferSubscription>()));
.Returns(new DeleteConnectorData(false, null, null, default, Enumerable.Empty<ConnectorOfferSubscription>(), UserStatusId.ACTIVE, Guid.NewGuid()));

// Act
async Task Act() => await _logic.DeleteConnectorAsync(connectorId).ConfigureAwait(false);
Expand All @@ -657,7 +712,7 @@ public async Task DeleteConnectorAsync_WithPendingAndWithoutDocumentId_ThrowsFor
new ConnectorOfferSubscription(offerSubscriptionId3, OfferSubscriptionStatusId.PENDING),
};
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(A<Guid>._, _identity.CompanyId))
.Returns(new DeleteConnectorData(true, null, null, ConnectorStatusId.PENDING, connectorOfferSubscriptions));
.Returns(new DeleteConnectorData(true, null, null, ConnectorStatusId.PENDING, connectorOfferSubscriptions, UserStatusId.ACTIVE, Guid.NewGuid()));

// Act
async Task Act() => await _logic.DeleteConnectorAsync(connectorId).ConfigureAwait(false);
Expand All @@ -683,7 +738,7 @@ public async Task DeleteConnectorAsync_WithPendingAndDocumentId_ThrowsForbiddenE
new ConnectorOfferSubscription(offerSubscriptionId3, OfferSubscriptionStatusId.PENDING),
};
A.CallTo(() => _connectorsRepository.GetConnectorDeleteDataAsync(A<Guid>._, _identity.CompanyId))
.Returns(new DeleteConnectorData(true, selfDescriptionDocumentId, DocumentStatusId, ConnectorStatusId.PENDING, connectorOfferSubscriptions));
.Returns(new DeleteConnectorData(true, selfDescriptionDocumentId, DocumentStatusId, ConnectorStatusId.PENDING, connectorOfferSubscriptions, UserStatusId.ACTIVE, Guid.NewGuid()));

// Act
async Task Act() => await _logic.DeleteConnectorAsync(connectorId).ConfigureAwait(false);
Expand Down

0 comments on commit e426c9e

Please sign in to comment.