< Summary

Information
Class: Services.PartnerServices.PartnerAuditService
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/PartnerServices/PartnerAuditService.cs
Line coverage
100%
Covered lines: 28
Uncovered lines: 0
Coverable lines: 28
Total lines: 71
Line coverage: 100%
Branch coverage
71%
Covered branches: 10
Total branches: 14
Branch coverage: 71.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
WriteAsync()50%22100%
QueryAsync()75%88100%
Truncate(...)75%44100%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/PartnerServices/PartnerAuditService.cs

#LineLine coverage
 1using Microsoft.EntityFrameworkCore;
 2using OzonDomains.Models.Partners;
 3using OzonRepositories.Context;
 4
 5namespace Services.PartnerServices;
 6
 7public interface IPartnerAuditService
 8{
 9    Task WriteAsync(
 10        string action,
 11        PartnerActorKind actorKind,
 12        string actor,
 13        long? partnerId,
 14        bool success = true,
 15        string? details = null,
 16        string? orderNumber = null,
 17        string? ipAddress = null,
 18        CancellationToken ct = default);
 19
 20    Task<IReadOnlyList<PartnerAuditLog>> QueryAsync(PartnerAuditQuery query, CancellationToken ct = default);
 21}
 22
 5023public sealed class PartnerAuditService(ApplicationDbContext db) : IPartnerAuditService
 24{
 25    private const int MaxTake = 500;
 26
 27    public async Task WriteAsync(
 28        string action,
 29        PartnerActorKind actorKind,
 30        string actor,
 31        long? partnerId,
 32        bool success = true,
 33        string? details = null,
 34        string? orderNumber = null,
 35        string? ipAddress = null,
 36        CancellationToken ct = default)
 37    {
 9238        db.PartnerAuditLogs.Add(new PartnerAuditLog
 9239        {
 9240            Action = action,
 9241            ActorKind = actorKind,
 9242            Actor = Truncate(actor, 200) ?? "system",
 9243            PartnerId = partnerId,
 9244            Success = success,
 9245            Details = Truncate(details, 2000),
 9246            OrderNumber = Truncate(orderNumber, 100),
 9247            IpAddress = Truncate(ipAddress, 64),
 9248            OccurredAtUtc = DateTime.UtcNow
 9249        });
 9250        await db.SaveChangesAsync(ct);
 9251    }
 52
 53    public async Task<IReadOnlyList<PartnerAuditLog>> QueryAsync(PartnerAuditQuery query, CancellationToken ct = default
 54    {
 555        IQueryable<PartnerAuditLog> q = db.PartnerAuditLogs.AsNoTracking();
 956        if (query.PartnerId is { } pid) q = q.Where(x => x.PartnerId == pid);
 1057        if (!string.IsNullOrWhiteSpace(query.Action)) q = q.Where(x => x.Action == query.Action);
 558        if (query.FromUtc is { } from) q = q.Where(x => x.OccurredAtUtc >= from);
 559        if (query.ToUtc is { } to) q = q.Where(x => x.OccurredAtUtc <= to);
 60
 561        return await q
 562            .OrderByDescending(x => x.OccurredAtUtc)
 563            .ThenByDescending(x => x.Id)
 564            .Skip(Math.Max(0, query.Skip))
 565            .Take(Math.Clamp(query.Take, 1, MaxTake))
 566            .ToListAsync(ct);
 567    }
 68
 69    private static string? Truncate(string? value, int max) =>
 36870        value is null || value.Length <= max ? value : value[..max];
 71}