Skip to content

Commit 2f98c39

Browse files
committed
Merge branch 'improvement/model-interfaces' into develop
Reevaluated the view model interfaces. - Introduced new `ICoreTopicViewModel` interface with `Key` and `ContentType` (565273f, 527dee4, eef391c) - Introduced new `INavigableTopicViewModel` interface with `Title`, `ShorTitle`, and `WebPath` (adf7ff8) - Cross-applied interfaces that satisfied subsets of other interfaces; this includes applying: - `ICoreTopicViewModel` to `ITopicBindingModel` (3b5dda8) - `IAssociatedTopicBindingModel` to `ITopicViewModel` (8ad42b9) - `ITopicBindingModel` to `ITopicViewModel` (ffe775e) - `INavigableTopicViewModel` to `INavigationTopicViewModel<T>` (adf7ff8) - `INaviableTopicViewModel` to `IPageTopicViewModel` (c41d989) - Removed `IsHidden` from `ITopicViewModel`, `TopicViewModel`; hidden models are excluded by the `TopicMappingService`, so this doesn't provide value (68a4e83). - Marked the `IPageTopicViewModel` as obsolete; narrow applications are expected to use the `InavigableTopicViewModel` instead (745e562). - Marked core properties (e.g., `Key`, `ContentType`, &c.) as non-nullable and required to reflect the fact that these should always be present (1bf25be, bfa64f1). - Updated `TopicViewModelCollection` to use the much narrower (new) `ICoreTopicViewModel`, thus reducing the interface requirements of its `TItem` (eef391c).
2 parents f92ebde + eef391c commit 2f98c39

20 files changed

Lines changed: 200 additions & 124 deletions

OnTopic.AspNetCore.Mvc.Host/Views/Shared/_TopicAttributes.cshtml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
<li>ContentType: @Model.ContentType</li>
88
<li>UniqueKey: @Model.UniqueKey</li>
99
<li>WebPath: @Model.WebPath</li>
10-
<li>IsHidden? @Model.IsHidden</li>
1110
<li>LastModified: @Model.LastModified</li>
1211
<li>View: @Model.View</li>
1312
</ul>

OnTopic.Tests/BindingModels/BasicTopicBindingModel.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
| Project Topics Library
55
\=============================================================================================================================*/
66
using System.ComponentModel.DataAnnotations;
7+
using System.Diagnostics.CodeAnalysis;
78
using OnTopic.Models;
89

910
namespace OnTopic.Tests.BindingModels {
@@ -21,14 +22,15 @@ public class BasicTopicBindingModel : ITopicBindingModel {
2122

2223
public BasicTopicBindingModel() { }
2324

24-
public BasicTopicBindingModel(string? key, string? contentType) {
25+
public BasicTopicBindingModel(string key, string contentType) {
2526
Key = key;
2627
ContentType = contentType;
2728
}
2829

30+
[Required, NotNull, DisallowNull]
2931
public string? Key { get; init; }
3032

31-
[Required]
33+
[Required, NotNull, DisallowNull]
3234
public string? ContentType { get; init; }
3335

3436
} //Class

OnTopic.Tests/BindingModels/InvalidReferenceTypeTopicBindingModel.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44
| Project Topics Library
55
\=============================================================================================================================*/
66
using System;
7-
using OnTopic.Mapping.Annotations;
87
using OnTopic.Models;
9-
using OnTopic.ViewModels;
8+
using OnTopic.Tests.ViewModels;
109

1110
namespace OnTopic.Tests.BindingModels {
1211

@@ -24,7 +23,7 @@ public class InvalidReferenceTypeTopicBindingModel : BasicTopicBindingModel {
2423

2524
public InvalidReferenceTypeTopicBindingModel(string? key = null) : base(key, "Page") { }
2625

27-
public TopicViewModel BaseTopic { get; } = new();
26+
public EmptyViewModel BaseTopic { get; } = new();
2827

2928
} //Class
3029
} //Namespace

OnTopic.Tests/BindingModels/InvalidRelationshipBaseTypeTopicBindingModel.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
using System;
77
using System.Collections.ObjectModel;
88
using OnTopic.Models;
9-
using OnTopic.ViewModels;
9+
using OnTopic.Tests.ViewModels;
1010

1111
namespace OnTopic.Tests.BindingModels {
1212

@@ -24,7 +24,7 @@ public class InvalidRelationshipBaseTypeTopicBindingModel : BasicTopicBindingMod
2424

2525
public InvalidRelationshipBaseTypeTopicBindingModel(string? key = null) : base(key, "ContentTypeDescriptor") { }
2626

27-
public Collection<TopicViewModel> ContentTypes { get; } = new();
27+
public Collection<EmptyViewModel> ContentTypes { get; } = new();
2828

2929
} //Class
3030
} //Namespace

OnTopic.Tests/BindingModels/RecordTopicBindingModel.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
| Project Topics Library
55
\=============================================================================================================================*/
66
using System.ComponentModel.DataAnnotations;
7+
using System.Diagnostics.CodeAnalysis;
78
using OnTopic.Models;
89

910
namespace OnTopic.Tests.BindingModels {
@@ -22,9 +23,10 @@ public class RecordTopicBindingModel : ITopicBindingModel {
2223

2324
public RecordTopicBindingModel() { }
2425

26+
[Required, NotNull, DisallowNull]
2527
public string? Key { get; init; }
2628

27-
[Required]
29+
[Required, NotNull, DisallowNull]
2830
public string? ContentType { get; init; }
2931

3032
} //Class

OnTopic.Tests/TopicMappingServiceTest.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,11 @@ public async Task Map_Generic_ReturnsNewModel() {
8585

8686
topic.Attributes.SetValue("MetaTitle", "ValueA");
8787
topic.Attributes.SetValue("Title", "Value1");
88-
topic.Attributes.SetValue("IsHidden", "1");
8988

9089
var target = await _mappingService.MapAsync<PageTopicViewModel>(topic).ConfigureAwait(false);
9190

9291
Assert.AreEqual<string>("ValueA", target.MetaTitle);
9392
Assert.AreEqual<string>("Value1", target.Title);
94-
Assert.AreEqual<bool>(true, target.IsHidden);
9593

9694
}
9795

@@ -127,13 +125,11 @@ public async Task Map_Dynamic_ReturnsNewModel() {
127125

128126
topic.Attributes.SetValue("MetaTitle", "ValueA");
129127
topic.Attributes.SetValue("Title", "Value1");
130-
topic.Attributes.SetValue("IsHidden", "1");
131128

132129
var target = (PageTopicViewModel?)await _mappingService.MapAsync(topic).ConfigureAwait(false);
133130

134131
Assert.AreEqual<string>("ValueA", target.MetaTitle);
135132
Assert.AreEqual<string>("Value1", target.Title);
136-
Assert.AreEqual<bool>(true, target.IsHidden);
137133

138134
}
139135

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*==============================================================================================================================
2+
| Author Ignia, LLC
3+
| Client Ignia, LLC
4+
| Project Topics Library
5+
\=============================================================================================================================*/
6+
using OnTopic.Models;
7+
8+
namespace OnTopic.Tests.ViewModels {
9+
10+
/*============================================================================================================================
11+
| VIEW MODEL: EMPTY
12+
\---------------------------------------------------------------------------------------------------------------------------*/
13+
/// <summary>
14+
/// A view model that does not implement any properties or interfaces. This will be invalid for mapping models that expect
15+
/// e.g. <see cref="IAssociatedTopicBindingModel"/> or <see cref="ITopicBindingModel"/>.
16+
/// </summary>
17+
/// <remarks>
18+
/// This is a sample class intended for test purposes only; it is not designed for use in a production environment.
19+
/// </remarks>
20+
public class EmptyViewModel {
21+
22+
}
23+
}

OnTopic.ViewModels/BindingModels/AssociatedTopicBindingModel.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
| Project Topics Library
55
\=============================================================================================================================*/
66
using System.ComponentModel.DataAnnotations;
7+
using System.Diagnostics.CodeAnalysis;
78
using OnTopic.Mapping.Reverse;
89
using OnTopic.Models;
910

@@ -32,7 +33,7 @@ public record AssociatedTopicBindingModel : IAssociatedTopicBindingModel {
3233
/// <requires description="The value from the getter must not be null." exception="T:System.ArgumentNullException">
3334
/// value is not null
3435
/// </requires>
35-
[Required]
36+
[Required, NotNull, DisallowNull]
3637
public string? UniqueKey { get; init; }
3738

3839
} //Class

OnTopic.ViewModels/NavigationTopicViewModel.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
\=============================================================================================================================*/
66
using System;
77
using System.Collections.ObjectModel;
8+
using System.ComponentModel.DataAnnotations;
9+
using System.Diagnostics.CodeAnalysis;
810
using OnTopic.Models;
911

1012
namespace OnTopic.ViewModels {
@@ -34,6 +36,7 @@ public sealed record NavigationTopicViewModel : INavigationTopicViewModel<Naviga
3436
| TITLE
3537
\-------------------------------------------------------------------------------------------------------------------------*/
3638
/// <inheritdoc cref="TopicViewModel"/>
39+
[Required, NotNull, DisallowNull]
3740
public string? Title { get; init; }
3841

3942
/*==========================================================================================================================
@@ -48,6 +51,7 @@ public sealed record NavigationTopicViewModel : INavigationTopicViewModel<Naviga
4851
| WEB PATH
4952
\-------------------------------------------------------------------------------------------------------------------------*/
5053
/// <inheritdoc cref="WebPath"/>
54+
[Required, NotNull, DisallowNull]
5155
public string? WebPath { get; init; }
5256

5357
/*==========================================================================================================================

OnTopic.ViewModels/TopicViewModel.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
| Project Topics Library
55
\=============================================================================================================================*/
66
using System;
7+
using System.ComponentModel.DataAnnotations;
8+
using System.Diagnostics.CodeAnalysis;
79
using OnTopic.Mapping.Annotations;
810
using OnTopic.Models;
911

@@ -20,7 +22,7 @@ namespace OnTopic.ViewModels {
2022
/// default implementations that can be used directly, used as base classes, or overwritten at the presentation level. They
2123
/// are supplied for convenience to model factory default settings for out-of-the-box content types.
2224
/// </remarks>
23-
public record TopicViewModel: ITopicViewModel {
25+
public record TopicViewModel: ITopicViewModel, ICoreTopicViewModel, IAssociatedTopicBindingModel, ITopicBindingModel {
2426

2527
/*==========================================================================================================================
2628
| ID
@@ -32,24 +34,28 @@ public record TopicViewModel: ITopicViewModel {
3234
| KEY
3335
\-------------------------------------------------------------------------------------------------------------------------*/
3436
/// <inheritdoc />
37+
[Required, NotNull, DisallowNull]
3538
public string? Key { get; init; }
3639

3740
/*==========================================================================================================================
3841
| CONTENT TYPE
3942
\-------------------------------------------------------------------------------------------------------------------------*/
4043
/// <inheritdoc />
44+
[Required, NotNull, DisallowNull]
4145
public string? ContentType { get; init; }
4246

4347
/*==========================================================================================================================
4448
| UNIQUE KEY
4549
\-------------------------------------------------------------------------------------------------------------------------*/
4650
/// <inheritdoc />
51+
[Required, NotNull, DisallowNull]
4752
public string? UniqueKey { get; init; }
4853

4954
/*==========================================================================================================================
5055
| WEB PATH
5156
\-------------------------------------------------------------------------------------------------------------------------*/
5257
/// <inheritdoc />
58+
[Required, NotNull, DisallowNull]
5359
public string? WebPath { get; init; }
5460

5561
/*==========================================================================================================================
@@ -62,12 +68,15 @@ public record TopicViewModel: ITopicViewModel {
6268
| TITLE
6369
\-------------------------------------------------------------------------------------------------------------------------*/
6470
/// <inheritdoc />
71+
[Required, NotNull, DisallowNull]
6572
public string? Title { get; init; }
6673

6774
/*==========================================================================================================================
6875
| IS HIDDEN?
6976
\-------------------------------------------------------------------------------------------------------------------------*/
70-
/// <inheritdoc />
77+
/// <inheritdoc/>
78+
[Obsolete("The IsHidden property is no longer supported by TopicViewModel.", true)]
79+
[DisableMapping]
7180
public bool IsHidden { get; init; }
7281

7382
/*==========================================================================================================================

0 commit comments

Comments
 (0)