Skip to content

Commit

Permalink
[YOMA-66] Ensure unique names per entity for links that supports mult…
Browse files Browse the repository at this point in the history
…iple links per action (#761)

* Ensure unique names per entity for links that supports multiple links per action

* Linting

* Ensure opportunity is published, supports verification of type manual for instant-verify link creation
  • Loading branch information
adrianwium authored Apr 25, 2024
1 parent 31f702b commit 35f4ac9
Show file tree
Hide file tree
Showing 6 changed files with 2,377 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -112,18 +112,22 @@ public async Task<Link> Create(LinkRequestCreate request, bool ensureOrganizatio
ModifiedByUserId = user.Id,
};

Link? itemExisting = null;
IQueryable<Link>? queryItemExisting = null;
switch (request.EntityType)
{
case LinkEntityType.Opportunity:
item.OpportunityId = request.EntityId;

queryItemExisting = _linkRepository.Query().Where(o => o.EntityType == item.EntityType && o.Action == item.Action && o.OpportunityId == item.OpportunityId);

switch (request.Action)
{
case LinkAction.Share:
if (request.UsagesLimit.HasValue || request.DateEnd.HasValue)
throw new ValidationException($"Neither a usage limit nor an end date is supported by the link with action '{request.Action}'.");

var itemExisting = _linkRepository.Query().SingleOrDefault(o => o.EntityType == item.EntityType && o.Action == item.Action && o.OpportunityId == item.OpportunityId);
itemExisting = queryItemExisting.SingleOrDefault();
if (itemExisting == null) break;

if (!string.Equals(itemExisting.URL, item.URL))
Expand All @@ -138,6 +142,12 @@ public async Task<Link> Create(LinkRequestCreate request, bool ensureOrganizatio
if (!request.UsagesLimit.HasValue && !request.DateEnd.HasValue)
throw new ValidationException($"Either a usage limit or an end date is required for the link with action '{request.Action}'.");

#pragma warning disable CA1862 // Use the 'StringComparison' method overloads to perform case-insensitive string comparisons
itemExisting = queryItemExisting.Where(o => o.Name.ToLower() == item.Name.ToLower()).SingleOrDefault();
#pragma warning restore CA1862 // Use the 'StringComparison' method overloads to perform case-insensitive string comparisons
if (itemExisting != null)
throw new ValidationException($"Link with name '{item.Name}' already exists for the opportunity");

item.URL = item.URL.AppendPathSegment(item.Id.ToString());
break;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1425,12 +1425,15 @@ public async Task<LinkInfo> CreateLinkInstantVerify(Guid id, OpportunityRequestL
{
ArgumentNullException.ThrowIfNull(request, nameof(request));

var opportunity = GetById(id, false, false, ensureOrganizationAuthorization);
var opportunity = GetById(id, false, true, ensureOrganizationAuthorization);

await _opportunityRequestLinkInstantVerifyValidator.ValidateAndThrowAsync(request);

if (opportunity.Status != Status.Active)
throw new ValidationException($"Link cannot be created as the opportunity '{opportunity.Title}' is not active");
if (!opportunity.VerificationEnabled || opportunity.VerificationMethod != VerificationMethod.Manual)
throw new ValidationException($"Link cannot be created as the opportunity '{opportunity.Title}' does not support manual verification");

if (!opportunity.Published)
throw new ValidationException($"Link cannot be created as the opportunity '{opportunity.Title}' has not been published");

if (string.IsNullOrEmpty(request.Name)) request.Name = opportunity.Title.RemoveSpecialCharacters();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Yoma.Core.Infrastructure.Database.ActionLink.Entities
[Table("Link", Schema = "ActionLink")]
[Index(nameof(URL), IsUnique = true)]
[Index(nameof(ShortURL), IsUnique = true)]
[Index(nameof(EntityType), nameof(Action), nameof(StatusId), nameof(OpportunityId), nameof(DateEnd), nameof(DateCreated))]
[Index(nameof(Name), nameof(EntityType), nameof(Action), nameof(StatusId), nameof(OpportunityId), nameof(DateEnd), nameof(DateCreated))]
public class Link : BaseEntity<Guid>
{
[Required]
Expand Down
Loading

0 comments on commit 35f4ac9

Please sign in to comment.