< Summary

Information
Class: OzonOrdersWeb.Authorization.Discovery.FieldDiscoveryService
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Authorization/Discovery/FieldDiscoveryService.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 49
Coverable lines: 49
Total lines: 86
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 20
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
DiscoverAsync()0%210140%
SyncAllAsync()0%2040%
GetTypesWithDiscoverFields()0%2040%
Key(...)100%210%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Authorization/Discovery/FieldDiscoveryService.cs

#LineLine coverage
 1using System.ComponentModel.DataAnnotations;
 2using System.Reflection;
 3using Microsoft.EntityFrameworkCore;
 4using OzonDomains.Models.Authorization;
 5using OzonDomains.Models.Authorization.Enums;
 6using OzonRepositories.Context;
 7
 8namespace OzonOrdersWeb.Authorization.Discovery;
 9
 10public sealed class FieldDiscoveryService : IFieldDiscoveryService
 11{
 12    private readonly ApplicationDbContext _db;
 13
 014    public FieldDiscoveryService(ApplicationDbContext db)
 15    {
 016        _db = db;
 017    }
 18
 19    public async Task<List<DiscoveredField>> DiscoverAsync(CancellationToken ct = default)
 20    {
 021        var existing = await _db.AppFields.AsNoTracking()
 022            .Select(f => new { f.EntityName, f.FieldName })
 023            .ToListAsync(ct);
 024        var existingSet = existing
 25            .Select(e => Key(e.EntityName, e.FieldName))
 026            .ToHashSet(StringComparer.OrdinalIgnoreCase);
 27
 028        var result = new List<DiscoveredField>();
 029        var seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
 030        foreach (var type in GetTypesWithDiscoverFields())
 31        {
 032            var attr = type.GetCustomAttribute<DiscoverFieldsAttribute>()!;
 033            foreach (var prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
 34            {
 035                if (!prop.CanRead || !prop.CanWrite) continue;
 036                var key = Key(attr.EntityName, prop.Name);
 037                if (!seen.Add(key)) continue;
 38
 039                var displayAttr = prop.GetCustomAttribute<DisplayAttribute>();
 040                var displayName = displayAttr?.Name ?? prop.Name;
 041                result.Add(new DiscoveredField
 042                {
 043                    EntityName = attr.EntityName,
 044                    FieldName = prop.Name,
 045                    DisplayName = displayName,
 046                    ExistsInDb = existingSet.Contains(key),
 047                });
 48            }
 49        }
 50        return result.OrderBy(r => r.ExistsInDb).ThenBy(r => r.EntityName).ThenBy(r => r.FieldName).ToList();
 051    }
 52
 53    public async Task<int> SyncAllAsync(CancellationToken ct = default)
 54    {
 055        var found = await DiscoverAsync(ct);
 056        var added = 0;
 57        foreach (var d in found.Where(d => !d.ExistsInDb))
 58        {
 059            _db.AppFields.Add(new AppField
 060            {
 061                EntityName = d.EntityName,
 062                FieldName = d.FieldName,
 063                DisplayName = d.DisplayName,
 064                FieldType = FieldType.FormField,
 065                IsActive = true
 066            });
 067            added++;
 68        }
 069        if (added > 0) await _db.SaveChangesAsync(ct);
 070        return added;
 071    }
 72
 73    private static IEnumerable<Type> GetTypesWithDiscoverFields()
 74    {
 075        return AppDomain.CurrentDomain.GetAssemblies()
 076            .Where(a => !a.IsDynamic)
 077            .SelectMany(a =>
 078            {
 079                try { return a.GetTypes(); }
 080                catch { return Array.Empty<Type>(); }
 081            })
 082            .Where(t => t.IsClass && !t.IsAbstract && t.GetCustomAttribute<DiscoverFieldsAttribute>() is not null);
 83    }
 84
 085    private static string Key(string entity, string field) => $"{entity.ToLowerInvariant()}|{field.ToLowerInvariant()}";
 86}