< Summary - Jellyfin

Information
Class: MediaBrowser.Controller.Entities.PeopleHelper
Assembly: MediaBrowser.Controller
File(s): /srv/git/jellyfin/MediaBrowser.Controller/Entities/PeopleHelper.cs
Line coverage
51%
Covered lines: 19
Uncovered lines: 18
Coverable lines: 37
Total lines: 104
Line coverage: 51.3%
Branch coverage
29%
Covered branches: 10
Total branches: 34
Branch coverage: 29.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 5/6/2026 - 12:15:23 AM Line coverage: 47.2% (17/36) Branch coverage: 35.7% (10/28) Total lines: 1008/6/2026 - 12:17:15 AM Line coverage: 51.3% (19/37) Branch coverage: 29.4% (10/34) Total lines: 104 5/6/2026 - 12:15:23 AM Line coverage: 47.2% (17/36) Branch coverage: 35.7% (10/28) Total lines: 1008/6/2026 - 12:17:15 AM Line coverage: 51.3% (19/37) Branch coverage: 29.4% (10/34) Total lines: 104

Coverage delta

Coverage delta 7 -7

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
AddPerson(...)50%311865.38%
IsSameCredit(...)16.66%14640%
IsCastKind(...)0%2040%
MergeExisting(...)0%4260%

File(s)

/srv/git/jellyfin/MediaBrowser.Controller/Entities/PeopleHelper.cs

#LineLine coverage
 1#pragma warning disable CS1591
 2
 3using System;
 4using System.Collections.Generic;
 5using System.Linq;
 6using Jellyfin.Data.Enums;
 7using MediaBrowser.Model.Entities;
 8
 9namespace MediaBrowser.Controller.Entities
 10{
 11    public static class PeopleHelper
 12    {
 13        public static void AddPerson(ICollection<PersonInfo> people, PersonInfo person)
 14        {
 6315            ArgumentNullException.ThrowIfNull(person);
 6316            ArgumentException.ThrowIfNullOrEmpty(person.Name);
 17
 6318            person.Name = person.Name.Trim();
 19
 20            // Normalize
 6321            if (string.Equals(person.Role, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase))
 22            {
 023                person.Type = PersonKind.GuestStar;
 24            }
 6325            else if (string.Equals(person.Role, PersonType.Director, StringComparison.OrdinalIgnoreCase))
 26            {
 027                person.Type = PersonKind.Director;
 28            }
 6329            else if (string.Equals(person.Role, PersonType.Producer, StringComparison.OrdinalIgnoreCase))
 30            {
 031                person.Type = PersonKind.Producer;
 32            }
 6333            else if (string.Equals(person.Role, PersonType.Writer, StringComparison.OrdinalIgnoreCase))
 34            {
 035                person.Type = PersonKind.Writer;
 36            }
 37
 38            // Check for dupes based on the combination of Name, Type and Role.
 6339            var existing = people.FirstOrDefault(p => IsSameCredit(p, person)
 6340                && string.Equals(p.Role ?? string.Empty, person.Role ?? string.Empty, StringComparison.OrdinalIgnoreCase
 41
 6342            if (existing is null)
 43            {
 6344                if (string.IsNullOrEmpty(person.Role))
 45                {
 946                    existing = people.FirstOrDefault(p => IsSameCredit(p, person));
 47                }
 48                else
 49                {
 50                    // If the person already exists without a role and we have one, fill it in
 5451                    existing = people.FirstOrDefault(p => IsSameCredit(p, person) && string.IsNullOrEmpty(p.Role));
 5452                    if (existing is not null)
 53                    {
 054                        existing.Role = person.Role;
 55                    }
 56                }
 57            }
 58
 6359            if (existing is null)
 60            {
 6361                people.Add(person);
 6362                return;
 63            }
 64
 65            // If the type is GuestStar and there's already an Actor entry, then promote it to avoid dupes
 066            if (person.Type == PersonKind.GuestStar)
 67            {
 068                existing.Type = PersonKind.GuestStar;
 69            }
 70
 071            MergeExisting(existing, person);
 072        }
 73
 74        private static bool IsSameCredit(PersonInfo existing, PersonInfo person)
 75        {
 69476            if (!string.Equals(existing.Name, person.Name, StringComparison.OrdinalIgnoreCase))
 77            {
 69478                return false;
 79            }
 80
 81            // Actor and GuestStar describe the same credit, a guest star is just a promoted actor.
 082            if (IsCastKind(existing.Type) && IsCastKind(person.Type))
 83            {
 084                return true;
 85            }
 86
 087            return existing.Type == person.Type;
 88        }
 89
 90        private static bool IsCastKind(PersonKind kind)
 091            => kind is PersonKind.Actor or PersonKind.GuestStar;
 92
 93        private static void MergeExisting(PersonInfo existing, PersonInfo person)
 94        {
 095            existing.SortOrder = person.SortOrder ?? existing.SortOrder;
 096            existing.ImageUrl = person.ImageUrl ?? existing.ImageUrl;
 97
 098            foreach (var id in person.ProviderIds)
 99            {
 0100                existing.SetProviderId(id.Key, id.Value);
 101            }
 0102        }
 103    }
 104}