Skip to content

Commit 6f3b206

Browse files
authored
Bugfix/fix va bugs discovered (#884)
* Fix validation lenght for questions * Rework export data * Add last updated at column, fix rating questions display * fix build * Cleanup tests
1 parent 081da77 commit 6f3b206

File tree

279 files changed

+31186
-8979
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

279 files changed

+31186
-8979
lines changed

.env.example

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ Core__HangfireConnectionConfig__Server=postgresql-local
1919
Core__HangfireConnectionConfig__Port=5432
2020
Core__HangfireConnectionConfig__Database=vote-monitor
2121
Core__HangfireConnectionConfig__UserId=postgres
22-
Core__HangfireConnectionConfig__Password=docker
22+
Core__HangfireConnectionConfig__Password=docker
23+
24+
MINIO_ROOT_USER: minioadmin
25+
MINIO_ROOT_PASSWORD: minioadmin

api/src/Feature.Attachments/Complete/Endpoint.cs renamed to api/src/Feature.Attachments/CompleteUpload/Endpoint.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using Microsoft.AspNetCore.Authorization;
44
using Vote.Monitor.Core.Services.FileStorage.Contracts;
55

6-
namespace Feature.Attachments.Complete;
6+
namespace Feature.Attachments.CompleteUpload;
77

88
public class Endpoint(
99
IAuthorizationService authorizationService,

api/src/Feature.Attachments/Complete/Request.cs renamed to api/src/Feature.Attachments/CompleteUpload/Request.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using Vote.Monitor.Core.Security;
22

3-
namespace Feature.Attachments.Complete;
3+
namespace Feature.Attachments.CompleteUpload;
44

55
public class Request
66
{

api/src/Feature.Attachments/Complete/Validator.cs renamed to api/src/Feature.Attachments/CompleteUpload/Validator.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace Feature.Attachments.Complete;
1+
namespace Feature.Attachments.CompleteUpload;
22

33
public class Validator : Validator<Request>
44
{
@@ -9,6 +9,5 @@ public Validator()
99
RuleFor(x => x.Id).NotEmpty();
1010
RuleFor(x => x.UploadId).NotEmpty();
1111
RuleFor(x => x.Etags).NotEmpty();
12-
RuleForEach(x => x.Etags).NotEmpty();
1312
}
1413
}

api/src/Feature.Attachments/Create/Endpoint.cs

Lines changed: 0 additions & 86 deletions
This file was deleted.

api/src/Feature.Attachments/Create/Request.cs

Lines changed: 0 additions & 19 deletions
This file was deleted.

api/src/Feature.Attachments/Create/Validator.cs

Lines changed: 0 additions & 17 deletions
This file was deleted.

api/src/Feature.Attachments/InitiateUpload/Endpoint.cs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using Feature.Attachments.Specifications;
33
using Microsoft.AspNetCore.Authorization;
44
using Vote.Monitor.Core.Services.FileStorage.Contracts;
5+
using Vote.Monitor.Core.Services.Time;
56
using Vote.Monitor.Domain.Entities.MonitoringObserverAggregate;
67

78
namespace Feature.Attachments.InitiateUpload;
@@ -10,7 +11,8 @@ public class Endpoint(
1011
IAuthorizationService authorizationService,
1112
IRepository<AttachmentAggregate> repository,
1213
IFileStorageService fileStorageService,
13-
IReadRepository<MonitoringObserver> monitoringObserverRepository)
14+
IReadRepository<MonitoringObserver> monitoringObserverRepository,
15+
ITimeProvider timeProvider)
1416
: Endpoint<Request, Results<Ok<Response>, NotFound, Conflict>>
1517
{
1618
public override void Configure()
@@ -20,38 +22,46 @@ public override void Configure()
2022
Options(x => x.WithTags("attachments", "mobile"));
2123
Summary(s =>
2224
{
23-
s.Summary = "Creates an attachment for a specific polling station and gets back details for uploading it in the file storage";
25+
s.Summary =
26+
"Creates an attachment for a specific polling station and gets back details for uploading it in the file storage";
2427
});
2528
}
2629

27-
public override async Task<Results<Ok<Response>, NotFound, Conflict>> ExecuteAsync(Request req, CancellationToken ct)
30+
public override async Task<Results<Ok<Response>, NotFound, Conflict>> ExecuteAsync(Request req,
31+
CancellationToken ct)
2832
{
29-
var authorizationResult = await authorizationService.AuthorizeAsync(User, new MonitoringObserverRequirement(req.ElectionRoundId));
33+
var authorizationResult =
34+
await authorizationService.AuthorizeAsync(User, new MonitoringObserverRequirement(req.ElectionRoundId));
3035
if (!authorizationResult.Succeeded)
3136
{
3237
return TypedResults.NotFound();
3338
}
3439

3540
var specification = new GetAttachmentByIdSpecification(req.ElectionRoundId, req.ObserverId, req.Id);
36-
var existingAttachment = await repository.FirstOrDefaultAsync(specification, ct);
37-
if (existingAttachment != null)
41+
var duplicatedAttachmentExist = await repository.AnyAsync(specification, ct);
42+
if (duplicatedAttachmentExist)
3843
{
3944
return TypedResults.Conflict();
4045
}
4146

42-
var monitoringObserverSpecification = new GetMonitoringObserverSpecification(req.ElectionRoundId, req.ObserverId);
43-
var monitoringObserver = await monitoringObserverRepository.FirstOrDefaultAsync(monitoringObserverSpecification, ct);
47+
var monitoringObserverSpecification =
48+
new GetMonitoringObserverIdSpecification(req.ElectionRoundId, req.ObserverId);
49+
var monitoringObserverId =
50+
await monitoringObserverRepository.FirstOrDefaultAsync(monitoringObserverSpecification, ct);
51+
52+
var uploadPath =
53+
$"elections/{req.ElectionRoundId}/polling-stations/{req.PollingStationId}/form/{req.FormId}/attachments";
4454

45-
var uploadPath = $"elections/{req.ElectionRoundId}/polling-stations/{req.PollingStationId}/form/{req.FormId}/attachments";
46-
var attachment = AttachmentAggregate.CreateV2(req.Id,
55+
var attachment = AttachmentAggregate.Create(req.Id,
4756
req.ElectionRoundId,
4857
req.PollingStationId,
49-
monitoringObserver!.Id,
58+
monitoringObserverId,
5059
req.FormId,
5160
req.QuestionId,
5261
req.FileName,
5362
uploadPath,
54-
req.ContentType);
63+
req.ContentType,
64+
req.LastUpdatedAt ?? timeProvider.UtcNow);
5565

5666
var uploadResult = await fileStorageService.CreateMultipartUploadAsync(uploadPath,
5767
fileName: attachment.UploadedFileName,
@@ -63,8 +73,7 @@ public override async Task<Results<Ok<Response>, NotFound, Conflict>> ExecuteAsy
6373

6474
return TypedResults.Ok(new Response
6575
{
66-
UploadId = uploadResult.UploadId,
67-
UploadUrls = uploadResult.PresignedUrls
76+
UploadId = uploadResult.UploadId, UploadUrls = uploadResult.PresignedUrls
6877
});
6978
}
7079
}

api/src/Feature.Attachments/InitiateUpload/Request.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,9 @@ public class Request
1717
public string FileName { get; set; }
1818
public string ContentType { get; set; }
1919
public int NumberOfUploadParts { get; set; }
20+
21+
/// <summary>
22+
/// Temporary made nullable until we release a mobile version that will always send this property.
23+
/// </summary>
24+
public DateTime? LastUpdatedAt { get; set; }
2025
}

api/src/Feature.Attachments/InitiateUpload/Validator.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,21 @@ public Validator()
1111
RuleFor(x => x.FormId).NotEmpty();
1212
RuleFor(x => x.QuestionId).NotEmpty();
1313
RuleFor(x => x.NumberOfUploadParts).GreaterThan(0);
14+
RuleFor(x => x.FileName).NotEmpty();
15+
RuleFor(x => x.ContentType).NotEmpty();
16+
17+
RuleFor(x => x.LastUpdatedAt)
18+
.Must(BeUtc)
19+
.WithMessage("LastUpdatedAt must be in UTC format.");
20+
}
21+
22+
private bool BeUtc(DateTime? date)
23+
{
24+
if (!date.HasValue)
25+
{
26+
return true;
27+
}
28+
29+
return date.Value.Kind == DateTimeKind.Utc;
1430
}
1531
}

0 commit comments

Comments
 (0)