< Summary - Core.Tests

Information
Class: Common.Core.Models.Person
Assembly: Common.Core
File(s): D:\a\NuGetPackages\NuGetPackages\src\Common\Core\Models\Person.cs
Tag: 3_8508158812
Line coverage
100%
Covered lines: 153
Uncovered lines: 0
Coverable lines: 153
Total lines: 317
Line coverage: 100%
Branch coverage
98%
Covered branches: 59
Total branches: 60
Branch coverage: 98.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
get_Id()100%11100%
set_Id(...)100%22100%
get_FirstName()100%22100%
set_FirstName(...)100%22100%
get_MiddleName()100%11100%
set_MiddleName(...)100%22100%
get_LastName()100%22100%
set_LastName(...)100%22100%
get_Address()100%11100%
set_Address(...)100%22100%
get_GovernmentNumber()100%11100%
set_GovernmentNumber(...)100%22100%
get_IdProvince()100%11100%
set_IdProvince(...)100%22100%
get_IdNumber()100%11100%
set_IdNumber(...)100%22100%
get_HomePhone()100%11100%
set_HomePhone(...)100%22100%
get_BirthDate()100%11100%
set_BirthDate(...)100%22100%
get_FullName()100%22100%
Clone()50%22100%
Equals(...)100%44100%
Update(...)100%66100%
GetSerializerOptions()100%11100%
Read(...)100%11100%
UpdateSQL(...)100%1010100%
UpdateOthers(...)100%1212100%

File(s)

D:\a\NuGetPackages\NuGetPackages\src\Common\Core\Models\Person.cs

#LineLine coverage
 1using System.ComponentModel.DataAnnotations;
 2using System.ComponentModel.DataAnnotations.Schema;
 3using System.Data;
 4using System.Text.Json;
 5using System.Text.Json.Serialization;
 6using Common.Core.Classes;
 7using Common.Core.Converters;
 8using Common.Core.Interfaces;
 9
 10namespace Common.Core.Models;
 11
 12/// <summary>This class contains details of a Person.</summary>
 13public class Person : ModelEdit, IPerson
 14{
 15  /// <summary>Default name of the Person data file.</summary>
 16  public const string cDefaultFile = "Person.json";
 17
 18  #region Private Variables
 19
 20  private int _id;
 21  private string? _firstName;
 22  private string? _middleName;
 23  private string? _lastName;
 3024  private Address _address = new();
 25  private string? _governmentNumber;
 26  private string? _idProvince;
 27  private string? _idNumber;
 28  private string? _homePhone;
 29  private DateOnly? _birthDate;
 30
 31  #endregion
 32
 33  #region IPerson Properties
 34
 35  /// <inheritdoc/>
 36  public override int Id
 37  {
 5038    get => _id;
 39    set
 3140    {
 3141      if( value != _id )
 3042      {
 3043        _id = value;
 3044        OnPropertyChanged( nameof( Id ) );
 3045      }
 3146    }
 47  }
 48
 49  /// <inheritdoc/>
 50  [Required]
 51  [MaxLength( 50 )]
 52  public string FirstName
 53  {
 5054    get => ( _firstName is not null ) ? _firstName : string.Empty;
 55    set
 3156    {
 3157      if( !value.Equals( _firstName ) )
 3158      {
 3159        _firstName = value;
 3160        OnPropertyChanged( nameof( FirstName ) );
 3161        OnPropertyChanged( nameof( FullName ) );
 3162      }
 3163    }
 64  }
 65
 66  /// <inheritdoc/>
 67  [JsonIgnore( Condition = JsonIgnoreCondition.WhenWritingNull )]
 68  [MaxLength( 50 )]
 69  public string? MiddleName
 70  {
 4671    get => _middleName;
 72    set
 3173    {
 3174      if( value != _middleName )
 1175      {
 1176        _middleName = SetNullString( value );
 1177        OnPropertyChanged( nameof( MiddleName ) );
 1178        OnPropertyChanged( nameof( FullName ) );
 1179      }
 3180    }
 81  }
 82
 83  /// <inheritdoc/>
 84  [Required]
 85  [MaxLength( 50 )]
 86  public string LastName
 87  {
 4688    get => ( _lastName is not null ) ? _lastName : string.Empty;
 89    set
 3190    {
 3191      if( !value.Equals( _lastName ) )
 3192      {
 3193        _lastName = value;
 3194        OnPropertyChanged( nameof( LastName ) );
 3195        OnPropertyChanged( nameof( FullName ) );
 3196      }
 3197    }
 98  }
 99
 100  /// <inheritdoc/>
 101  public Address Address
 102  {
 36103    get => _address;
 104    set
 28105    {
 28106      if( value != _address )
 28107      {
 28108        _address = value;
 28109        OnPropertyChanged( nameof( Address ) );
 28110      }
 28111    }
 112  }
 113
 114  /// <inheritdoc/>
 115  [MaxLength( 50 )]
 116  [JsonIgnore( Condition = JsonIgnoreCondition.WhenWritingNull )]
 117  public string? GovernmentNumber
 118  {
 19119    get => _governmentNumber;
 120    set
 31121    {
 31122      if( value != _governmentNumber )
 31123      {
 31124        _governmentNumber = SetNullString( value );
 31125        OnPropertyChanged( nameof( GovernmentNumber ) );
 31126      }
 31127    }
 128  }
 129
 130  /// <inheritdoc/>
 131  [MaxLength( 50 )]
 132  [JsonIgnore( Condition = JsonIgnoreCondition.WhenWritingNull )]
 133  public string? IdProvince
 134  {
 19135    get => _idProvince;
 136    set
 31137    {
 31138      if( value != _idProvince )
 31139      {
 31140        _idProvince = SetNullString( value );
 31141        OnPropertyChanged( nameof( IdProvince ) );
 31142      }
 31143    }
 144  }
 145
 146  /// <inheritdoc/>
 147  [MaxLength( 50 )]
 148  [JsonIgnore( Condition = JsonIgnoreCondition.WhenWritingNull )]
 149  public string? IdNumber
 150  {
 19151    get => _idNumber;
 152    set
 31153    {
 31154      if( value != _idNumber )
 31155      {
 31156        _idNumber = SetNullString( value );
 31157        OnPropertyChanged( nameof( IdNumber ) );
 31158      }
 31159    }
 160  }
 161
 162  /// <inheritdoc/>
 163  [MaxLength( 50 )]
 164  [JsonIgnore( Condition = JsonIgnoreCondition.WhenWritingNull )]
 165  public string? HomePhone
 166  {
 18167    get => _homePhone;
 168    set
 30169    {
 30170      if( value != _homePhone )
 23171      {
 23172        _homePhone = SetNullString( value );
 23173        OnPropertyChanged( nameof( HomePhone ) );
 23174      }
 30175    }
 176  }
 177
 178  /// <inheritdoc/>
 179  [Column( TypeName = "date" )]
 180  [JsonIgnore( Condition = JsonIgnoreCondition.WhenWritingNull )]
 181  [JsonConverter( typeof( JsonDateOnlyString ) )]
 182  public DateOnly? BirthDate
 183  {
 24184    get => _birthDate;
 185    set
 32186    {
 32187      if( !value.Equals( _birthDate ) )
 32188      {
 32189        _birthDate = value;
 32190        OnPropertyChanged( nameof( BirthDate ) );
 32191      }
 32192    }
 193  }
 194
 195  /// <inheritdoc/>
 196  [NotMapped]
 197  [JsonIgnore]
 198  public string FullName
 199  {
 200    get
 3201    {
 3202      var values = new[] { FirstName.Trim(), MiddleName?.Trim(), LastName.Trim() };
 12203      return string.Join( " ", values.Where( s => !string.IsNullOrEmpty( s ) ) );
 3204    }
 205  }
 206
 207  #endregion
 208
 209  #region Public Methods
 210
 211  /// <inheritdoc/>
 212  public override object Clone()
 3213  {
 3214    return ReflectionHelper.CreateDeepCopy( this ) as Person ?? new Person();
 3215  }
 216
 217  /// <inheritdoc/>
 218  /// <param name="obj">An object implementing the IPerson interface to compare with this object.</param>
 219  public override bool Equals( object? obj )
 16220  {
 20221    if( obj is null || obj is not IPerson other ) { return false; }
 14222    return ReflectionHelper.IsEqual( this, other );
 16223  }
 224
 225  /// <inheritdoc/>
 226  /// <param name="obj">An object implementing the IPerson interface with the changed values.</param>
 227  public override void Update( object? obj )
 3228  {
 7229    if( obj is null || obj is not IPerson other || other is not Person person ) { return; }
 230
 1231    ReflectionHelper.ApplyChanges( person, this );
 3232  }
 233
 234  /// <summary>Gets the Json serializer options for Person objects.</summary>
 235  /// <returns>A JsonSerializerOptions object.</returns>
 236  public static JsonSerializerOptions GetSerializerOptions()
 1237  {
 1238    var rtn = JsonHelper.DefaultSerializerOptions();
 1239    rtn.Converters.Add( new InterfaceFactory( typeof( Person ), typeof( IPerson ) ) );
 1240    rtn.NumberHandling = JsonNumberHandling.AllowReadingFromString;
 241
 1242    return rtn;
 1243  }
 244
 245  /// <summary>Builds a Person object from a database table row.</summary>
 246  /// <param name="row">Database row containing the Person columns.</param>
 247  /// <param name="addPrefix">Table column prefix for Address fields if required.</param>
 248  /// <returns>Person object containing the database values.</returns>
 249  /// <remarks>This method assumes that the table column names are the same as the property names.</remarks>
 250  public static Person Read( DataRow row, string addPrefix = "" )
 7251  {
 7252    return new Person()
 7253    {
 7254      Id = row.Field<int>( nameof( Id ) ),
 7255      FirstName = row.Field<string>( nameof( FirstName ) )!,
 7256      MiddleName = row.Field<string?>( nameof( MiddleName ) ),
 7257      LastName = row.Field<string>( nameof( LastName ) )!,
 7258      Address = Address.BuildAddress( row, addPrefix ),
 7259      GovernmentNumber = row.Field<string?>( nameof( GovernmentNumber ) ),
 7260      IdProvince = row.Field<string?>( nameof( IdProvince ) ),
 7261      IdNumber = row.Field<string?>( nameof( IdNumber ) ),
 7262      HomePhone = row.Field<string?>( nameof( HomePhone ) ),
 7263      BirthDate = DateOnly.FromDateTime( row.Field<DateTime>( nameof( BirthDate ) ) )
 7264    };
 7265  }
 266
 267  /// <summary>Builds the SQL script for any value changes.</summary>
 268  /// <param name="row">Database row containing the current Person data.</param>
 269  /// <param name="obj">IPerson object containing the original values.</param>
 270  /// <param name="mod">IPerson object containing the modified values.</param>
 271  /// <param name="addPrefix">Table column name prefix for Address fields (if required).</param>
 272  /// <returns>An empty string is returned if no changes were found.</returns>
 273  /// <remarks>This method assumes that the table column names are the same as the property names.</remarks>
 274  public static string UpdateSQL( DataRow row, IPerson obj, IPerson mod, string addPrefix = "" )
 4275  {
 4276    IList<string> sql = new List<string>();
 4277    Person cur = Read( row, addPrefix );
 6278    if( cur.Id != mod.Id ) { return string.Empty; }
 279
 3280    if( !cur.Equals( obj ) )
 1281    {
 1282      mod.FirstName = cur.FirstName;
 1283      mod.MiddleName = cur.MiddleName;
 1284      mod.LastName = cur.LastName;
 1285      mod.Address = cur.Address;
 1286      mod.GovernmentNumber = cur.GovernmentNumber;
 1287      mod.IdProvince = cur.IdProvince;
 1288      mod.IdNumber = cur.IdNumber;
 1289      mod.BirthDate = cur.BirthDate;
 1290      return string.Empty;
 291    }
 292
 8293    if( obj.FirstName != mod.FirstName ) { SetSQLColumn( nameof( FirstName ), mod.FirstName, sql ); }
 8294    if( obj.MiddleName != mod.MiddleName ) { SetSQLColumn( nameof( MiddleName ), mod.MiddleName, sql ); }
 8295    if( obj.LastName != mod.LastName ) { SetSQLColumn( nameof( LastName ), mod.LastName, sql ); }
 2296    _ = Address.UpdateAddress( obj.Address, mod.Address, cur.Address, sql, addPrefix );
 2297    UpdateOthers( obj, mod, sql );
 298
 2299    return string.Join( ", ", sql );
 4300  }
 301
 302  #endregion
 303
 304  private static void UpdateOthers( IPerson obj, IPerson mod, IList<string> sql )
 2305  {
 8306    if( obj.GovernmentNumber != mod.GovernmentNumber ) { SetSQLColumn( nameof( GovernmentNumber ), mod.GovernmentNumber,
 8307    if( obj.IdProvince != mod.IdProvince ) { SetSQLColumn( nameof( IdProvince ), mod.IdProvince, sql ); }
 8308    if( obj.IdNumber != mod.IdNumber ) { SetSQLColumn( nameof( IdNumber ), mod.IdNumber, sql ); }
 8309    if( obj.HomePhone != mod.HomePhone ) { SetSQLColumn( nameof( HomePhone ), mod.HomePhone, sql ); }
 2310    if( !obj.BirthDate.Equals( mod.BirthDate ) )
 2311    {
 312      // Special handling for DateOnly format
 2313      string? val = mod.BirthDate?.ToString( "yyyy-MM-dd" );
 2314      SetSQLColumn( nameof( BirthDate ), val, sql );
 2315    }
 2316  }
 317}