Skip to content

Commit 367d102

Browse files
committed
Merge pull request #2 from AshleyPoole/add-build-tests
Adding unit tests
2 parents 2226cb8 + 6543b7a commit 367d102

14 files changed

+726
-38
lines changed

README.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ This wrapper easies the communication to the API's for .NET developers which all
88
**Notes**
99
- SSL Labs' Assessment API's are currently still in development and are subject to change. This therefore may impact the wrapper though updates will be provided.
1010
- The wrapper does **NOT** use web scrapping like other wrappers which don't use the assessment API's.
11-
- This documentation is for v1.0.2 release.
1211

1312
### NuGet Package
1413
The wrapper can easily be imported into your project using the [SSLLWrapper NuGet package](https://www.nuget.org/packages/SSLLWrapper/). The NuGet install command for this package is:
@@ -168,9 +167,6 @@ public enum All
168167
}
169168
```
170169

171-
#### To Do
172-
- Flesh out SSLWrapper.Tests
173-
174170
### Author
175171
Ashley Poole - www.ashleypoole.co.uk.
176172

SSLLWrapper.Tests/AnalyzeTests.cs

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
using System.Linq;
2+
using System.Security.Cryptography.X509Certificates;
3+
using FluentAssertions;
4+
using Microsoft.VisualStudio.TestTools.UnitTesting;
5+
using Moq;
6+
using SSLLWrapper;
7+
using SSLLWrapper.Interfaces;
8+
using SSLLWrapper.Models;
9+
using SSLLWrapper.Models.Response;
10+
using SSLLWrapper.Tests;
11+
12+
namespace given_that_I_make_a_analyze_request
13+
{
14+
[TestClass]
15+
public class when_a_valid_request_is_made_with_just_a_hostname_and_the_scan_has_completed : PositiveTests
16+
{
17+
[ClassInitialize]
18+
public static void Setup(TestContext testContext)
19+
{
20+
var mockedApiProvider = new Mock<IApiProvider>();
21+
TestHost = "https://www.ashleypoole.co.uk";
22+
var webResponseModel = new WebResponseModel()
23+
{
24+
Payloay = "{\"host\":\"https://www.ashleypoole.co.uk\",\"port\":443,\"protocol\":\"HTTPS\",\"isPublic\":false,\"status\":\"READY\",\"" +
25+
"startTime\":1422115006431,\"testTime\":1422115131804,\"engineVersion\":\"1.12.8\",\"criteriaVersion\":\"2009i\",\"" +
26+
"endpoints\":[{\"ipAddress\":\"104.28.6.2\",\"statusMessage\":\"Ready\",\"grade\":\"A\",\"hasWarnings\":false,\"" +
27+
"isExceptional\":false,\"progress\":100,\"duration\":64286,\"eta\":2393,\"delegation\":3},{\"ipAddress\":\"104.28.7.2\"" +
28+
",\"statusMessage\":\"Ready\",\"grade\":\"A\",\"hasWarnings\":false,\"isExceptional\":false,\"progress\":100,\"duration\"" +
29+
":61046,\"eta\":2393,\"delegation\":3}]}",
30+
StatusCode = 200,
31+
StatusDescription = "Ok",
32+
Url = ("https://api.dev.ssllabs.com/api/fa78d5a4/analyze?host=" + TestHost)
33+
};
34+
35+
mockedApiProvider.Setup(x => x.MakeGetRequest(It.IsAny<RequestModel>())).Returns(webResponseModel);
36+
37+
var ssllService = new SSLLService("https://api.dev.ssllabs.com/api/fa78d5a4/", mockedApiProvider.Object);
38+
Response = ssllService.Analyze(TestHost);
39+
}
40+
41+
[TestMethod]
42+
public void then_the_scan_results_should_not_be_public()
43+
{
44+
Response.isPublic.Should().BeFalse();
45+
}
46+
}
47+
48+
[TestClass]
49+
public class when_a_valid_request_is_made_with_just_a_hostname_and_the_scan_is_at_resolving_stage: PositiveTests
50+
{
51+
[ClassInitialize]
52+
public static void Setup(TestContext testContext)
53+
{
54+
var mockedApiProvider = new Mock<IApiProvider>();
55+
TestHost = "https://www.ashleypoole.co.uk";
56+
var webResponseModel = new WebResponseModel()
57+
{
58+
Payloay = "{\"host\":\"https://www.ashleypoole.co.uk\",\"port\":443,\"protocol\":\"HTTP\",\"isPublic\":false,\"status\":\"DNS\"" +
59+
",\"statusMessage\":\"Resolving domain names\",\"startTime\":1422475200798,\"engineVersion\":\"1.12.8\"," +
60+
"\"criteriaVersion\":\"2009i\"}",
61+
StatusCode = 200,
62+
StatusDescription = "Ok",
63+
Url = ("https://api.dev.ssllabs.com/api/fa78d5a4/analyze?host=" + TestHost)
64+
};
65+
66+
mockedApiProvider.Setup(x => x.MakeGetRequest(It.IsAny<RequestModel>())).Returns(webResponseModel);
67+
68+
var ssllService = new SSLLService("https://api.dev.ssllabs.com/api/fa78d5a4/", mockedApiProvider.Object);
69+
Response = ssllService.Analyze(TestHost);
70+
}
71+
72+
[TestMethod]
73+
public void then_the_scan_results_should_not_be_public()
74+
{
75+
Response.isPublic.Should().BeFalse();
76+
}
77+
}
78+
79+
[TestClass]
80+
public class when_a_valid_request_is_made_with_all_the_inputs_and_the_scan_is_at_endpoint_scanning_stage : PositiveTests
81+
{
82+
[ClassInitialize]
83+
public static void Setup(TestContext testContext)
84+
{
85+
var mockedApiProvider = new Mock<IApiProvider>();
86+
TestHost = "https://www.ashleypoole.co.uk";
87+
var webResponseModel = new WebResponseModel()
88+
{
89+
Payloay = "{\"host\":\"https://www.ashleypoole.co.uk\",\"port\":443,\"protocol\":\"HTTP\",\"isPublic\":true,\"" +
90+
"status\":\"IN_PROGRESS\",\"startTime\":1422479488403,\"engineVersion\":\"1.12.8\",\"criteriaVersion\":\"2009i\"" +
91+
",\"endpoints\":[{\"ipAddress\":\"104.28.6.2\",\"statusMessage\":\"In progress\",\"statusDetails\":\"TESTING_HTTPS\"" +
92+
",\"statusDetailsMessage\":\"Sending one complete HTTPS request\",\"progress\":-1,\"eta\":-1,\"delegation\":3}," +
93+
"{\"ipAddress\":\"104.28.7.2\",\"statusMessage\":\"Pending\",\"progress\":-1,\"eta\":-1,\"delegation\":3}]}",
94+
StatusCode = 200,
95+
StatusDescription = "Ok",
96+
Url = ("https://api.dev.ssllabs.com/api/fa78d5a4/analyze?host=" + TestHost + "&publish=on&all=done")
97+
};
98+
99+
mockedApiProvider.Setup(x => x.MakeGetRequest(It.IsAny<RequestModel>())).Returns(webResponseModel);
100+
101+
var ssllService = new SSLLService("https://api.dev.ssllabs.com/api/fa78d5a4/", mockedApiProvider.Object);
102+
Response = ssllService.Analyze(TestHost, SSLLService.Publish.On, SSLLService.ClearCache.On,
103+
SSLLService.FromCache.Ignore, SSLLService.All.Done);
104+
}
105+
106+
[TestMethod]
107+
public void then_the_scan_results_should_be_public()
108+
{
109+
Response.isPublic.Should().BeTrue();
110+
}
111+
}
112+
113+
[TestClass]
114+
public class when_a_invalid_request_is_made_with_all_the_inputs_and_the_scan_is_unable_to_resolve_hostname : NegativeTests
115+
{
116+
[ClassInitialize]
117+
public static void Setup(TestContext testContext)
118+
{
119+
var mockedApiProvider = new Mock<IApiProvider>();
120+
TestHost = "https://www2.ashleypoole.co.uk";
121+
var webResponseModel = new WebResponseModel()
122+
{
123+
Payloay = "{\"host\":\"https://www2.ashleypoole.co.uk\",\"port\":443,\"protocol\":\"HTTP\",\"isPublic\":false,\"status\":\"ERROR\"," +
124+
"\"statusMessage\":\"Unable to resolve domain name\",\"startTime\":1422478797953,\"testTime\":1422478798017," +
125+
"\"engineVersion\":\"1.12.8\",\"criteriaVersion\":\"2009i\",\"cacheExpiryTime\":1422478858017}",
126+
StatusCode = 200,
127+
StatusDescription = "Ok",
128+
Url = ("https://api.dev.ssllabs.com/api/fa78d5a4/analyze?host=" + TestHost)
129+
};
130+
131+
mockedApiProvider.Setup(x => x.MakeGetRequest(It.IsAny<RequestModel>())).Returns(webResponseModel);
132+
133+
var ssllService = new SSLLService("https://api.dev.ssllabs.com/api/fa78d5a4/", mockedApiProvider.Object);
134+
Response = ssllService.Analyze(TestHost, SSLLService.Publish.On, SSLLService.ClearCache.On,
135+
SSLLService.FromCache.Ignore, SSLLService.All.Done);
136+
}
137+
138+
[TestMethod]
139+
public void then_the_status_code_should_be_valid_for_response()
140+
{
141+
Response.Header.statusCode.Should().Be(200);
142+
}
143+
}
144+
145+
[TestClass]
146+
public class when_a_invalid_request_is_made_with_both_clearCache_and_fromCache : NegativeTests
147+
{
148+
[ClassInitialize]
149+
public static void Setup(TestContext testContext)
150+
{
151+
var mockedApiProvider = new Mock<IApiProvider>();
152+
TestHost = "https://www.ashleypoole.co.uk";
153+
var webResponseModel = new WebResponseModel()
154+
{
155+
Payloay = "{\"errors\":[{\"message\":\"Parameters \u0027fromCache\u0027 and \u0027clearCache\u0027 cannot be used at the same time\"}]}",
156+
StatusCode = 400,
157+
StatusDescription = "Ok",
158+
Url = ("https://api.dev.ssllabs.com/api/fa78d5a4/analyze?host=" + TestHost + "&clearCache=on&fromCache=on&all=done")
159+
};
160+
161+
mockedApiProvider.Setup(x => x.MakeGetRequest(It.IsAny<RequestModel>())).Returns(webResponseModel);
162+
163+
var ssllService = new SSLLService("https://api.dev.ssllabs.com/api/fa78d5a4/", mockedApiProvider.Object);
164+
Response = ssllService.Analyze(TestHost, SSLLService.Publish.On, SSLLService.ClearCache.On,
165+
SSLLService.FromCache.Ignore, SSLLService.All.Done);
166+
}
167+
}
168+
169+
[TestClass]
170+
public class when_a_invalid_request_is_made_with_malformed_url_hostname : NegativeTests
171+
{
172+
[ClassInitialize]
173+
public static void Setup(TestContext testContext)
174+
{
175+
var mockedApiProvider = new Mock<IApiProvider>();
176+
TestHost = "www.ashleypoole.somereallybadurl";
177+
178+
var ssllService = new SSLLService("https://api.dev.ssllabs.com/api/fa78d5a4/", mockedApiProvider.Object);
179+
Response = ssllService.Analyze(TestHost);
180+
}
181+
182+
[TestMethod]
183+
public void then_preflight_error_should_be_thrown()
184+
{
185+
Response.Errors.Any(x => x.message == "Host does not pass preflight validation. No Api call has been made.").Should().BeTrue();
186+
}
187+
}
188+
189+
public abstract class PositiveTests : GenericPositiveTests<Analyze>
190+
{
191+
public static string TestHost;
192+
193+
[TestMethod]
194+
public void then_the_host_property_should_match_the_requested_hostname()
195+
{
196+
Response.host.Should().Be(TestHost);
197+
}
198+
199+
[TestMethod]
200+
public void then_the_header_status_code_should_be_200()
201+
{
202+
Response.Header.statusCode.Should().Be(200);
203+
}
204+
205+
[TestMethod]
206+
public void then_the_port_should_be_that_of_a_ssl_connection()
207+
{
208+
Response.port.Should().Be(443);
209+
}
210+
}
211+
212+
public abstract class NegativeTests : GenericNegativeTests<Analyze>
213+
{
214+
public static string TestHost;
215+
216+
[TestMethod]
217+
public void then_an_error_occurred_should_be_marked()
218+
{
219+
Response.HasErrorOccurred.Should().BeTrue();
220+
}
221+
222+
[TestMethod]
223+
public void then_at__least_one_error_should_be_thrown()
224+
{
225+
Response.Errors.Count.Should().BeGreaterOrEqualTo(1);
226+
}
227+
}
228+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using FluentAssertions;
2+
using Microsoft.VisualStudio.TestTools.UnitTesting;
3+
using SSLLWrapper.Interfaces;
4+
5+
namespace SSLLWrapper.Tests
6+
{
7+
public class GenericNegativeTests<T> where T : IBaseResponse
8+
{
9+
public static T Response;
10+
11+
[TestMethod]
12+
public void then_at_least_one_error_should_be_thrown()
13+
{
14+
Response.Errors.Count.Should().BeGreaterOrEqualTo(1);
15+
}
16+
17+
[TestMethod]
18+
public void then_the_HasErrorOccurred_should_be_true()
19+
{
20+
Response.HasErrorOccurred.Should().BeTrue();
21+
}
22+
23+
[TestMethod]
24+
public void then_the_status_code_should_be_valid_for_response()
25+
{
26+
Response.Header.statusCode.Should().NotBe(200);
27+
}
28+
}
29+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using FluentAssertions;
2+
using Microsoft.VisualStudio.TestTools.UnitTesting;
3+
using SSLLWrapper.Interfaces;
4+
5+
namespace SSLLWrapper.Tests
6+
{
7+
public class GenericPositiveTests<T> where T : IBaseResponse
8+
{
9+
public static T Response;
10+
11+
[TestMethod]
12+
public void then_the_error_count_should_be_zero()
13+
{
14+
Response.Errors.Count.Should().Be(0);
15+
}
16+
17+
[TestMethod]
18+
public void then_the_HasErrorOccurred_should_be_false()
19+
{
20+
Response.HasErrorOccurred.Should().BeFalse();
21+
}
22+
}
23+
}

0 commit comments

Comments
 (0)