Skip to content

Commit dc96a4f

Browse files
committed
Added PassingFor to attributes (#34)
1 parent 655bfbb commit dc96a4f

File tree

7 files changed

+325
-16
lines changed

7 files changed

+325
-16
lines changed

src/MyTested.AspNetCore.Mvc.Abstractions/Builders/Attributes/BaseAttributesTestBuilder{TAttributesTestBuilder}.cs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,7 @@ protected BaseAttributesTestBuilder(ComponentTestContext testContext)
3131

3232
protected abstract TAttributesTestBuilder GetAttributesTestBuilder();
3333

34-
/// <summary>
35-
/// Tests whether the attributes contain the provided attribute type.
36-
/// </summary>
37-
/// <typeparam name="TAttribute">Type of expected attribute.</typeparam>
38-
/// <returns>The same test builder of <see cref="BaseAttributesTestBuilder{TAttributesBuilder}"/> type.</returns>
34+
/// <inheritdoc />
3935
public TAttributesTestBuilder ContainingAttributeOfType<TAttribute>()
4036
where TAttribute : Attribute
4137
{
@@ -53,6 +49,34 @@ public TAttributesTestBuilder ContainingAttributeOfType<TAttribute>()
5349
return this.AttributesBuilder;
5450
}
5551

52+
/// <inheritdoc />
53+
public TAttributesTestBuilder PassingFor<TAttribute>(Action<TAttribute> assertions)
54+
where TAttribute : Attribute
55+
{
56+
this.ContainingAttributeOfType<TAttribute>();
57+
this.Validations.Add(attrs => assertions(this.GetAttributeOfType<TAttribute>(attrs)));
58+
return this.AttributesBuilder;
59+
}
60+
61+
/// <inheritdoc />
62+
public TAttributesTestBuilder PassingFor<TAttribute>(Func<TAttribute, bool> predicate)
63+
where TAttribute : Attribute
64+
{
65+
this.ContainingAttributeOfType<TAttribute>();
66+
this.Validations.Add(attrs =>
67+
{
68+
var attribute = this.GetAttributeOfType<TAttribute>(attrs);
69+
if (!predicate(attribute))
70+
{
71+
this.ThrowNewAttributeAssertionException(
72+
$"{attribute.GetName()} passing the given predicate",
73+
"it failed");
74+
}
75+
});
76+
77+
return this.AttributesBuilder;
78+
}
79+
5680
/// <summary>
5781
/// Gets an attribute of the given type from the provided collection of objects and throws exception if such is not found.
5882
/// </summary>

src/MyTested.AspNetCore.Mvc.Abstractions/Builders/Contracts/Attributes/IBaseAttributesTestBuilder.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,29 @@
99
public interface IBaseAttributesTestBuilder<TAttributesTestBuilder>
1010
{
1111
/// <summary>
12-
/// Checks whether the collected attributes contain the provided attribute type.
12+
/// Tests whether the collected attributes contain the provided attribute type.
1313
/// </summary>
1414
/// <typeparam name="TAttribute">Type of expected attribute.</typeparam>
1515
/// <returns>The same attributes test builder.</returns>
1616
TAttributesTestBuilder ContainingAttributeOfType<TAttribute>()
1717
where TAttribute : Attribute;
18+
19+
/// <summary>
20+
/// Tests whether the collected attributes contain the provided attribute type passing the given assertions.
21+
/// </summary>
22+
/// <typeparam name="TAttribute">Type of expected attribute.</typeparam>
23+
/// <param name="assertions">Action containing assertions on the provided attribute.</param>
24+
/// <returns>The same attributes test builder.</returns>
25+
TAttributesTestBuilder PassingFor<TAttribute>(Action<TAttribute> assertions)
26+
where TAttribute : Attribute;
27+
28+
/// <summary>
29+
/// Tests whether the collected attributes contain the provided attribute type passing the given predicate.
30+
/// </summary>
31+
/// <typeparam name="TAttribute">Type of expected attribute.</typeparam>
32+
/// <param name="predicate">Predicate testing the provided attribute.</param>
33+
/// <returns>The same attributes test builder.</returns>
34+
TAttributesTestBuilder PassingFor<TAttribute>(Func<TAttribute, bool> predicate)
35+
where TAttribute : Attribute;
1836
}
1937
}

test/MyTested.AspNetCore.Mvc.Controllers.Test/BuildersTests/AttributesTests/ActionAttributesTestBuilderTests.cs

Lines changed: 94 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Setups.Controllers;
99
using Setups.Models;
1010
using Xunit;
11+
using System;
1112

1213
public class ActionAttributesTestBuilderTests
1314
{
@@ -195,7 +196,7 @@ public void SpecifyingAreaShouldThrowExceptionWithActionWithTheAttributeAndWrong
195196
.Instance()
196197
.Calling(c => c.OtherAttributes())
197198
.ShouldHave()
198-
.ActionAttributes(attributes => attributes.ChangingActionNameTo("AnotherArea"));
199+
.ActionAttributes(attributes => attributes.SpecifyingArea("AnotherArea"));
199200
},
200201
"When calling OtherAttributes action in MvcController expected action to have 'AnotherArea' area, but in fact found 'InArea'.");
201202
}
@@ -421,18 +422,88 @@ public void RestrictingForHttpMethodWithListOfHttpMethodsShouldWorkCorrectlyWith
421422
}
422423

423424
[Fact]
424-
public void AndAlsoShouldWorkCorrectly()
425+
public void PassingForShouldNotThrowExceptionWithCorrectAssertions()
425426
{
426427
MyController<MvcController>
427428
.Instance()
428429
.Calling(c => c.VariousAttributesAction())
429430
.ShouldHave()
430-
.ActionAttributes(attributes =>
431-
attributes
432-
.AllowingAnonymousRequests()
433-
.AndAlso()
434-
.DisablingActionCall()
435-
.ChangingActionNameTo("NormalAction"));
431+
.ActionAttributes(attributes => attributes
432+
.PassingFor<RouteAttribute>(route => Assert.Equal("/api/test", route.Template)));
433+
}
434+
435+
[Fact]
436+
public void PassingForShouldThrowExceptionWithIncorrectAssertions()
437+
{
438+
Assert.ThrowsAny<Exception>(
439+
() =>
440+
{
441+
MyController<MvcController>
442+
.Instance()
443+
.Calling(c => c.VariousAttributesAction())
444+
.ShouldHave()
445+
.ActionAttributes(attributes => attributes
446+
.PassingFor<RouteAttribute>(route => Assert.Equal("/invalid", route.Template)));
447+
});
448+
}
449+
450+
[Fact]
451+
public void PassingForShouldThrowExceptionWithIncorrectAttribute()
452+
{
453+
Test.AssertException<AttributeAssertionException>(
454+
() =>
455+
{
456+
MyController<MvcController>
457+
.Instance()
458+
.Calling(c => c.OtherAttributes())
459+
.ShouldHave()
460+
.ActionAttributes(attributes => attributes
461+
.PassingFor<ActionNameAttribute>(authorize => Assert.Equal("Admin", authorize.Name)));
462+
},
463+
"When calling OtherAttributes action in MvcController expected action to have ActionNameAttribute, but in fact such was not found.");
464+
}
465+
466+
[Fact]
467+
public void PassingForShouldNotThrowExceptionWithCorrectPredicate()
468+
{
469+
MyController<MvcController>
470+
.Instance()
471+
.Calling(c => c.VariousAttributesAction())
472+
.ShouldHave()
473+
.ActionAttributes(attributes => attributes
474+
.PassingFor<RouteAttribute>(route => route.Template == "/api/test"));
475+
}
476+
477+
[Fact]
478+
public void PassingForShouldThrowExceptionWithIncorrectPredicate()
479+
{
480+
Test.AssertException<AttributeAssertionException>(
481+
() =>
482+
{
483+
MyController<MvcController>
484+
.Instance()
485+
.Calling(c => c.VariousAttributesAction())
486+
.ShouldHave()
487+
.ActionAttributes(attributes => attributes
488+
.PassingFor<RouteAttribute>(route => route.Template == "/invalid"));
489+
},
490+
"When calling VariousAttributesAction action in MvcController expected action to have RouteAttribute passing the given predicate, but it failed.");
491+
}
492+
493+
[Fact]
494+
public void PassingForShouldThrowExceptionWithIncorrectAttributeWithPredicate()
495+
{
496+
Test.AssertException<AttributeAssertionException>(
497+
() =>
498+
{
499+
MyController<MvcController>
500+
.Instance()
501+
.Calling(c => c.OtherAttributes())
502+
.ShouldHave()
503+
.ActionAttributes(attributes => attributes
504+
.PassingFor<ActionNameAttribute>(authorize => authorize.Name == "Admin"));
505+
},
506+
"When calling OtherAttributes action in MvcController expected action to have ActionNameAttribute, but in fact such was not found.");
436507
}
437508

438509
[Fact]
@@ -444,5 +515,20 @@ public void WithNoShouldWorkCorrectly()
444515
.ShouldHave()
445516
.ActionAttributes(attributes => attributes.ChangingActionNameTo("Test"));
446517
}
518+
519+
[Fact]
520+
public void AndAlsoShouldWorkCorrectly()
521+
{
522+
MyController<MvcController>
523+
.Instance()
524+
.Calling(c => c.VariousAttributesAction())
525+
.ShouldHave()
526+
.ActionAttributes(attributes =>
527+
attributes
528+
.AllowingAnonymousRequests()
529+
.AndAlso()
530+
.DisablingActionCall()
531+
.ChangingActionNameTo("NormalAction"));
532+
}
447533
}
448534
}

test/MyTested.AspNetCore.Mvc.Controllers.Test/BuildersTests/AttributesTests/ControllerAttributesTestBuilder.cs

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
namespace MyTested.AspNetCore.Mvc.Test.BuildersTests.AttributesTests
22
{
3+
using System;
34
using Exceptions;
45
using Microsoft.AspNetCore.Authorization;
56
using Setups;
67
using Setups.Controllers;
78
using Xunit;
9+
using Microsoft.AspNetCore.Mvc;
810

911
public class ControllerAttributesTestBuilderTests
1012
{
@@ -143,7 +145,7 @@ public void SpecifyingAreaShouldThrowExceptionWithActionWithTheAttributeAndWrong
143145
.ShouldHave()
144146
.Attributes(attributes => attributes.SpecifyingArea("AnotherArea"));
145147
},
146-
"When testing MvcController was expected to have 'AnotherArea' area, but in fact found 'InArea'.");
148+
"When testing AreaController was expected to have 'AnotherArea' area, but in fact found 'CustomArea'.");
147149
}
148150

149151
[Fact]
@@ -229,6 +231,87 @@ public void RestrictingForAuthorizedRequestsShouldThrowExceptionWithControllerWi
229231
"When testing MvcController was expected to have AuthorizeAttribute with allowed 'Admin' roles, but in fact found 'Admin,Moderator'.");
230232
}
231233

234+
[Fact]
235+
public void PassingForShouldNotThrowExceptionWithCorrectAssertions()
236+
{
237+
MyController<MvcController>
238+
.Instance()
239+
.ShouldHave()
240+
.Attributes(attributes => attributes
241+
.PassingFor<AuthorizeAttribute>(authorize => Assert.Equal("Admin,Moderator", authorize.Roles)));
242+
}
243+
244+
[Fact]
245+
public void PassingForShouldThrowExceptionWithIncorrectAssertions()
246+
{
247+
Assert.ThrowsAny<Exception>(
248+
() =>
249+
{
250+
MyController<MvcController>
251+
.Instance()
252+
.ShouldHave()
253+
.Attributes(attributes => attributes
254+
.PassingFor<AuthorizeAttribute>(authorize => Assert.Equal("Admin", authorize.Roles)));
255+
});
256+
}
257+
258+
[Fact]
259+
public void PassingForShouldThrowExceptionWithIncorrectAttribute()
260+
{
261+
Test.AssertException<AttributeAssertionException>(
262+
() =>
263+
{
264+
MyController<MvcController>
265+
.Instance()
266+
.ShouldHave()
267+
.Attributes(attributes => attributes
268+
.PassingFor<ActionNameAttribute>(authorize => Assert.Equal("Admin", authorize.Name)));
269+
},
270+
"When testing MvcController was expected to have ActionNameAttribute, but in fact such was not found.");
271+
}
272+
273+
[Fact]
274+
public void PassingForShouldNotThrowExceptionWithCorrectPredicate()
275+
{
276+
MyController<MvcController>
277+
.Instance()
278+
.ShouldHave()
279+
.Attributes(attributes => attributes
280+
.PassingFor<AuthorizeAttribute>(authorize => authorize.Roles == "Admin,Moderator"));
281+
}
282+
283+
[Fact]
284+
public void PassingForShouldThrowExceptionWithIncorrectPredicate()
285+
{
286+
Test.AssertException<AttributeAssertionException>(
287+
() =>
288+
{
289+
MyController<MvcController>
290+
.Instance()
291+
.ShouldHave()
292+
.Attributes(attributes => attributes
293+
.PassingFor<AuthorizeAttribute>(authorize => authorize.Roles == "Admin"));
294+
},
295+
"When testing MvcController was expected to have AuthorizeAttribute passing the given predicate, but it failed.");
296+
}
297+
298+
[Fact]
299+
public void PassingForShouldThrowExceptionWithIncorrectAttributeWithPredicate()
300+
{
301+
Test.AssertException<AttributeAssertionException>(
302+
() =>
303+
{
304+
MyController<MvcController>
305+
.Instance()
306+
.ShouldHave()
307+
.Attributes(attributes => attributes
308+
.PassingFor<AuthorizeAttribute>(authorize => authorize.Roles == "Admin,Moderator")
309+
.AndAlso()
310+
.PassingFor<ActionNameAttribute>(authorize => authorize.Name == "Admin"));
311+
},
312+
"When testing MvcController was expected to have ActionNameAttribute, but in fact such was not found.");
313+
}
314+
232315
[Fact]
233316
public void AndAlsoShouldWorkCorrectly()
234317
{

test/MyTested.AspNetCore.Mvc.Controllers.Test/BuildersTests/ShouldPassForTests/ShouldPassForTestBuilderWithControllerTests.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Setups;
66
using Setups.Controllers;
77
using Xunit;
8+
using System;
89

910
public class ShouldPassForTestBuilderWithControllerTests
1011
{
@@ -22,6 +23,23 @@ public void ControllerAssertionsShouldWorkCorrectly()
2223
});
2324
}
2425

26+
[Fact]
27+
public void ControllerAssertionsShouldWorkCorrectlyAndThrowExceptionIfIncorrect()
28+
{
29+
Assert.ThrowsAny<Exception>(() =>
30+
{
31+
MyController<MvcController>
32+
.Instance()
33+
.Calling(c => c.FullOkAction())
34+
.ShouldReturn()
35+
.Ok()
36+
.ShouldPassForThe<MvcController>(controller =>
37+
{
38+
Assert.Null(controller);
39+
});
40+
});
41+
}
42+
2543
[Fact]
2644
public void ControllerPredicateShouldWorkCorrectly()
2745
{

test/MyTested.AspNetCore.Mvc.Test.Setups/Controllers/MvcController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ public IActionResult VariousAttributesAction()
299299
return this.Ok();
300300
}
301301

302-
[Area("Admin")]
302+
[Area("InArea")]
303303
public IActionResult OtherAttributes()
304304
{
305305
return this.Ok();

0 commit comments

Comments
 (0)