-
Notifications
You must be signed in to change notification settings - Fork 60
Expand file tree
/
Copy pathAuthenticatorKeyUriTests.cs
More file actions
123 lines (106 loc) · 4.32 KB
/
AuthenticatorKeyUriTests.cs
File metadata and controls
123 lines (106 loc) · 4.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using TechnitiumLibrary.Security.OTP;
namespace TechnitiumLibrary.UnitTests.TechnitiumLibrary.Security.OTP
{
[TestClass]
public sealed class AuthenticatorKeyUriTests
{
[TestMethod]
public void Constructor_ShouldAssignFieldsProperly()
{
AuthenticatorKeyUri uri = new AuthenticatorKeyUri(
"totp",
"ExampleCorp",
"user@example.com",
"SECRET123",
algorithm: "SHA256",
digits: 8,
period: 45);
Assert.AreEqual("totp", uri.Type);
Assert.AreEqual("ExampleCorp", uri.Issuer);
Assert.AreEqual("user@example.com", uri.AccountName);
Assert.AreEqual("SECRET123", uri.Secret);
Assert.AreEqual("SHA256", uri.Algorithm);
Assert.AreEqual(8, uri.Digits);
Assert.AreEqual(45, uri.Period);
}
[TestMethod]
public void Constructor_ShouldRejectInvalidDigitRange()
{
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() =>
_ = new AuthenticatorKeyUri("totp", "X", "Y", "ABC", digits: 5));
}
[TestMethod]
public void Constructor_ShouldRejectNegativePeriod()
{
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() =>
_ = new AuthenticatorKeyUri("totp", "X", "Y", "ABC", period: -1));
}
[TestMethod]
public void Generate_ShouldProduceValidInstance()
{
AuthenticatorKeyUri uri = AuthenticatorKeyUri.Generate(
issuer: "Corp",
accountName: "user@example.com",
keySize: 10);
Assert.AreEqual("totp", uri.Type);
Assert.AreEqual("Corp", uri.Issuer);
Assert.AreEqual("user@example.com", uri.AccountName);
Assert.IsNotNull(uri.Secret);
Assert.IsGreaterThanOrEqualTo(8, uri.Secret.Length, "Base32 length must be greater than raw bytes");
}
[TestMethod]
public void ToString_ShouldContainEncodedParameters()
{
AuthenticatorKeyUri uri = new AuthenticatorKeyUri(
"totp", "ACME", "alice@example.com", "SECRETKEY");
string uriString = uri.ToString();
Assert.Contains("otpauth://", uriString);
Assert.Contains("issuer=ACME", uriString);
Assert.Contains("alice%40example.com", uriString); // corrected expectation
}
[TestMethod]
public void Parse_ShouldRoundTripFromToString()
{
AuthenticatorKeyUri original = new AuthenticatorKeyUri(
"totp",
"Example",
"bob@example.com",
"BASESECRET",
algorithm: "SHA512",
digits: 8,
period: 45);
string serialized = original.ToString();
AuthenticatorKeyUri parsed = AuthenticatorKeyUri.Parse(serialized);
Assert.AreEqual(original.Type, parsed.Type);
Assert.AreEqual(original.Issuer, parsed.Issuer);
Assert.AreEqual(original.AccountName, parsed.AccountName);
Assert.AreEqual(original.Secret, parsed.Secret);
Assert.AreEqual(original.Algorithm, parsed.Algorithm);
Assert.AreEqual(original.Digits, parsed.Digits);
Assert.AreEqual(original.Period, parsed.Period);
}
[TestMethod]
public void Parse_ShouldRejectInvalidUriScheme()
{
Assert.ThrowsExactly<ArgumentException>(() =>
AuthenticatorKeyUri.Parse("http://notvalid"));
}
[TestMethod]
public void Parse_ShouldRejectMalformedUri()
{
Assert.ThrowsExactly<ArgumentNullException>(() =>
AuthenticatorKeyUri.Parse("otpauth://totp/INVALID")); // missing secret
}
[TestMethod]
public void GetQRCodePngImage_ShouldReturnNonEmptyByteArray()
{
AuthenticatorKeyUri uri = new AuthenticatorKeyUri(
"totp", "Issuer", "bob@example.com", "SECRETABC");
byte[] result = uri.GetQRCodePngImage();
Assert.IsNotNull(result);
Assert.IsGreaterThan(32, result.Length, "QR PNG must contain image bytes");
}
}
}