public static async Task GetSignature_WithRequest_WillReturnTheCorrectSignature(string method)
        {
            // Arrange
            var testData = await method.FromResource();

            var mAuthCore = new MAuthCore();

            var expectedSignature =
                ($"{testData.Method}\n" +
                 $"{testData.Url.AbsolutePath}\n" +
                 $"{testData.Base64Content.ToStringContent()}\n" +
                 $"{testData.ApplicationUuidString}\n" +
                 $"{testData.SignedTimeUnixSeconds}")
                .AsSHA512Hash();

            var authInfo = new PrivateKeyAuthenticationInfo()
            {
                ApplicationUuid = testData.ApplicationUuid,
                SignedTime      = testData.SignedTime
            };

            // Act
            var result = await mAuthCore.GetSignature(testData.ToHttpRequestMessage(), authInfo);

            // Assert
            Assert.Equal(expectedSignature, result);
        }
        public static async Task AddAuthenticationInfo_WithRequestAndAuthInfo_WillAddCorrectInformation(string method)
        {
            // Arrange
            var testData = await method.FromResource();

            var expectedMAuthHeader = testData.MAuthHeader;
            var mAuthCore           = new MAuthCore();

            var authInfo = new PrivateKeyAuthenticationInfo()
            {
                ApplicationUuid = testData.ApplicationUuid,
                SignedTime      = testData.SignedTime,
                PrivateKey      = TestExtensions.ClientPrivateKey
            };

            // Act
            var actual = await mAuthCore.AddAuthenticationInfo(testData.ToHttpRequestMessage(), authInfo);

            // Assert
            Assert.Equal(expectedMAuthHeader, actual.Headers.GetFirstValueOrDefault <string>(Constants.MAuthHeaderKey));
            Assert.Equal(
                authInfo.SignedTime.ToUnixTimeSeconds(),
                actual.Headers.GetFirstValueOrDefault <long>(Constants.MAuthTimeHeaderKey)
                );
        }
        public static async Task AuthenticateRequest_WithMWSVersion_WithDisableV1_WillThrowExceptionWithInvalidVersion(
            string method)
        {
            // Arrange
            var testData = await method.FromResource();

            var testOptions = TestExtensions.ServerOptions;

            testOptions.DisableV1 = true;
            var authenticator = new MAuthAuthenticator(testOptions, NullLogger <MAuthAuthenticator> .Instance);
            var mAuthCore     = new MAuthCore();

            var signedRequest = await mAuthCore
                                .AddAuthenticationInfo(testData.ToHttpRequestMessage(), new PrivateKeyAuthenticationInfo()
            {
                ApplicationUuid = testData.ApplicationUuid,
                PrivateKey      = TestExtensions.ClientPrivateKey,
                SignedTime      = testData.SignedTime
            });

            // Act
            var exception = (await Assert.ThrowsAsync <InvalidVersionException>(
                                 () => authenticator.AuthenticateRequest(signedRequest)));

            // Assert
            Assert.NotNull(exception);
            Assert.Equal("Authentication with MWS version is disabled.", exception.Message);
        }
        public static async Task AuthenticateRequest_AfterNumberOfAttempts_WillThrowExceptionWithRequestFailure(
            MAuthServiceRetryPolicy policy)
        {
            // Arrange
            var testData = await "GET".FromResource();

            var authenticator = new MAuthAuthenticator(TestExtensions.GetServerOptionsWithAttempts(
                                                           policy, shouldSucceedWithin: false), NullLogger <MAuthAuthenticator> .Instance);
            var mAuthCore = new MAuthCore();

            var signedRequest = await mAuthCore
                                .AddAuthenticationInfo(testData.ToHttpRequestMessage(), new PrivateKeyAuthenticationInfo()
            {
                ApplicationUuid = testData.ApplicationUuid,
                PrivateKey      = TestExtensions.ClientPrivateKey,
                SignedTime      = testData.SignedTime
            });

            // Act
            var exception = (await Assert.ThrowsAsync <AuthenticationException>(
                                 () => authenticator.AuthenticateRequest(signedRequest)));

            var innerException = exception.InnerException as RetriedRequestException;

            // Assert
            Assert.NotNull(innerException);
            Assert.Equal((int)policy + 1, innerException.Responses.Count);
            Assert.Equal(HttpStatusCode.ServiceUnavailable, innerException.Responses.First().StatusCode);
        }
        public static async Task CalculatePayload_WithBinaryContent_WillCalculateTheProperPayload()
        {
            // Arrange
            var testData  = await "POSTWithBinaryData".FromResource();
            var mAuthCore = new MAuthCore();

            // Act
            var result = await mAuthCore.CalculatePayload(testData.ToHttpRequestMessage(), new PrivateKeyAuthenticationInfo()
            {
                ApplicationUuid = testData.ApplicationUuid,
                SignedTime      = testData.SignedTime,
                PrivateKey      = TestExtensions.ClientPrivateKey
            });

            // Assert
            Assert.Equal(testData.Payload, result);
        }
        public static async Task SignRequest_WithMWSValidRequest_WillSignProperly(string method)
        {
            // Arrange
            var testData = await method.FromResource();

            var expectedMAuthHeader = testData.MAuthHeader;
            var mAuthCore           = new MAuthCore();

            // Act
            var actual = await mAuthCore.Sign(testData.ToHttpRequestMessage(), TestExtensions.ClientOptions(testData.SignedTime));

            // Assert
            Assert.Equal(expectedMAuthHeader, actual.Headers.GetFirstValueOrDefault <string>(Constants.MAuthHeaderKey));
            Assert.Equal(
                testData.SignedTime.ToUnixTimeSeconds(),
                actual.Headers.GetFirstValueOrDefault <long>(Constants.MAuthTimeHeaderKey)
                );
        }
        public static void Verify_WithCorrectlySignedData_WillVerifyTheDataAsValid()
        {
            // Arrange
            var signature    = "This is a signature.";
            var unsignedData = Encoding.UTF8.GetBytes(signature);

            var signer = new Pkcs1Encoding(new RsaEngine());

            signer.Init(true, TestExtensions.ClientPrivateKey.AsCipherParameters());

            var signedData = signer.ProcessBlock(unsignedData, 0, unsignedData.Length);

            var mAuthCore = new MAuthCore();

            // Act
            var result = mAuthCore.Verify(signedData, unsignedData, TestExtensions.ClientPublicKey);

            // Assert
            Assert.True(result);
        }
        public static async Task CalculatePayload_WithRequestAndAuthInfo_WillReturnCorrectPayload(string method)
        {
            // Arrange
            var testData = await method.FromResource();

            var mAuthCore = new MAuthCore();

            var authInfo = new PrivateKeyAuthenticationInfo()
            {
                ApplicationUuid = testData.ApplicationUuid,
                SignedTime      = testData.SignedTime,
                PrivateKey      = TestExtensions.ClientPrivateKey
            };

            // Act
            var result = await mAuthCore.CalculatePayload(testData.ToHttpRequestMessage(), authInfo);

            // Assert
            Assert.Equal(testData.Payload, result);
        }
        public static async Task Authenticate_WithValidRequest_WillAuthenticate(string method)
        {
            // Arrange
            var testData = await method.FromResourceV2();

            var mAuthCore = new MAuthCore();

            var signedRequest = await mAuthCore
                                .AddAuthenticationInfo(testData.ToDefaultHttpRequestMessage(), new PrivateKeyAuthenticationInfo()
            {
                ApplicationUuid = testData.ApplicationUuid,
                PrivateKey      = TestExtensions.ClientPrivateKey,
                SignedTime      = testData.SignedTime
            });

            // Act
            var isAuthenticated = await signedRequest.Authenticate(TestExtensions.ServerOptions, NullLogger.Instance);

            // Assert
            Assert.True(isAuthenticated);
        }