< Summary - Jellyfin

Information
Class: MediaBrowser.Controller.Entities.PeopleHelper
Assembly: MediaBrowser.Controller
File(s): /srv/git/jellyfin/MediaBrowser.Controller/Entities/PeopleHelper.cs
Line coverage
78%
Covered lines: 29
Uncovered lines: 8
Coverable lines: 37
Total lines: 104
Line coverage: 78.3%
Branch coverage
61%
Covered branches: 21
Total branches: 34
Branch coverage: 61.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 5/16/2026 - 12:15:55 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: 10410/29/2026 - 12:17:11 AM Line coverage: 78.3% (29/37) Branch coverage: 61.7% (21/34) Total lines: 104 5/16/2026 - 12:15:55 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: 10410/29/2026 - 12:17:11 AM Line coverage: 78.3% (29/37) Branch coverage: 61.7% (21/34) Total lines: 104

Coverage delta

Coverage delta 33 -33

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
AddPerson(...)55.55%271869.23%
IsSameCredit(...)66.66%6680%
IsCastKind(...)50%44100%
MergeExisting(...)50%6680%

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        {
 9815            ArgumentNullException.ThrowIfNull(person);
 9816            ArgumentException.ThrowIfNullOrEmpty(person.Name);
 17
 9818            person.Name = person.Name.Trim();
 19
 20            // Normalize
 9821            if (string.Equals(person.Role, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase))
 22            {
 023                person.Type = PersonKind.GuestStar;
 24            }
 9825            else if (string.Equals(person.Role, PersonType.Director, StringComparison.OrdinalIgnoreCase))
 26            {
 027                person.Type = PersonKind.Director;
 28            }
 9829            else if (string.Equals(person.Role, PersonType.Producer, StringComparison.OrdinalIgnoreCase))
 30            {
 031                person.Type = PersonKind.Producer;
 32            }
 9833            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.
 9839            var existing = people.FirstOrDefault(p => IsSameCredit(p, person)
 9840                && string.Equals(p.Role ?? string.Empty, person.Role ?? string.Empty, StringComparison.OrdinalIgnoreCase
 41
 9842            if (existing is null)
 43            {
 9644                if (string.IsNullOrEmpty(person.Role))
 45                {
 3246                    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
 6451                    existing = people.FirstOrDefault(p => IsSameCredit(p, person) && string.IsNullOrEmpty(p.Role));
 6452                    if (existing is not null)
 53                    {
 054                        existing.Role = person.Role;
 55                    }
 56                }
 57            }
 58
 9859            if (existing is null)
 60            {
 9661                people.Add(person);
 9662                return;
 63            }
 64
 65            // If the type is GuestStar and there's already an Actor entry, then promote it to avoid dupes
 266            if (person.Type == PersonKind.GuestStar)
 67            {
 068                existing.Type = PersonKind.GuestStar;
 69            }
 70
 271            MergeExisting(existing, person);
 272        }
 73
 74        private static bool IsSameCredit(PersonInfo existing, PersonInfo person)
 75        {
 72776            if (!string.Equals(existing.Name, person.Name, StringComparison.OrdinalIgnoreCase))
 77            {
 72578                return false;
 79            }
 80
 81            // Actor and GuestStar describe the same credit, a guest star is just a promoted actor.
 282            if (IsCastKind(existing.Type) && IsCastKind(person.Type))
 83            {
 084                return true;
 85            }
 86
 287            return existing.Type == person.Type;
 88        }
 89
 90        private static bool IsCastKind(PersonKind kind)
 291            => kind is PersonKind.Actor or PersonKind.GuestStar;
 92
 93        private static void MergeExisting(PersonInfo existing, PersonInfo person)
 94        {
 295            existing.SortOrder = person.SortOrder ?? existing.SortOrder;
 296            existing.ImageUrl = person.ImageUrl ?? existing.ImageUrl;
 97
 498            foreach (var id in person.ProviderIds)
 99            {
 0100                existing.SetProviderId(id.Key, id.Value);
 101            }
 2102        }
 103    }
 104}