#region License
// Copyright (c) 2005 Griffin Caprio & Choy Rim. All rights reserved.
#endregion
#region Imports
using System;
using System.Security;
using System.Threading;

using MbUnit.Core.Framework;
using MbUnit.Framework;

using DotNetMock.Framework.Security.Principal;
using DotNetMock.Examples.Security;
#endregion

namespace DotNetMock.Examples.MbUnitTests.Security
{
	[TestFixture]
	public class SensitiveClassTests 
	{
		private SensitiveClass sensitiveClass = null;
		private MockIIdentity mockIdentity = null;
		private MockIPrincipal mockPrincipal = null;

		[SetUp]
		public void Init() 
		{
			sensitiveClass = new SensitiveClass();
			mockIdentity = new MockIIdentity();
			mockPrincipal = new MockIPrincipal();
			mockPrincipal.SetExpectedIdentity( mockIdentity );

			Thread.CurrentPrincipal = mockPrincipal;
		}
		[TearDown]
		public void Destroy()
		{
			sensitiveClass = null;
			mockIdentity = null;
			mockPrincipal = null;
		}
		[Test]
		public void ManualCEOCheck()
		{
			mockIdentity.SetExpectedAuthenticationType( "NTLM" );
			mockIdentity.SetExpectedIsAuthenticated( true );
			mockIdentity.SetExpectedName( "Mr. CEO" );

			mockPrincipal.SetExpectedIsInRoleCount(1);
			mockPrincipal.AddExpectedRole( "CEO" );

			Assertion.Assert( "Cannot run Manual CEO Check!", sensitiveClass.CanRunManualCEOCheck() );
			
			verifyMocks();
		}
		[Test]
		public void CannotRunManualCEOCheck() 
		{
			mockIdentity.SetExpectedAuthenticationType( "NTLM" );
			mockIdentity.SetExpectedIsAuthenticated( true );
			mockIdentity.SetExpectedName( "Mr. Employee" );	

			mockPrincipal.SetExpectedIsInRoleCount(1);
			mockPrincipal.AddExpectedRole( "Employee" );

			Assertion.Assert( "Can run Manual CEO Check!", !sensitiveClass.CanRunManualCEOCheck() );
			verifyMocks();
		}
		[Test]
		public void NotAuthenticatedForCEOCheck()
		{
			mockIdentity.SetExpectedAuthenticationType( "NTLM" );
			mockIdentity.SetExpectedIsAuthenticated( false );
			mockIdentity.SetExpectedName( "Mr. Employee" );	
			
			mockPrincipal.SetExpectedIsInRoleCount(0);

			Assertion.Assert( "Authenticated!", !sensitiveClass.CanRunManualCEOCheck() );
			verifyMocks();
		}
		[Test]
		public void ImperativeCEOCheck() 
		{
			mockIdentity.SetExpectedAuthenticationType( "NTLM" );
			mockIdentity.SetExpectedIsAuthenticated( true );
			mockIdentity.SetExpectedName( "Mr. CEO" );

			mockPrincipal.SetExpectedIsInRoleCount(1);
			mockPrincipal.AddExpectedRole( "CEO" );

			Assertion.Assert( "Cannot run Imperative CEO Check!", sensitiveClass.CanRunImperativeCEOCheck() );
			
			verifyMocks();	
		}
		[Test]
		public void CannotRunImperativeCEOCheck() 
		{
			mockIdentity.SetExpectedAuthenticationType( "NTLM" );
			mockIdentity.SetExpectedIsAuthenticated( true );
			mockIdentity.SetExpectedName( "Mr. Employee" );

			mockPrincipal.SetExpectedIsInRoleCount(1);
			mockPrincipal.AddExpectedRole( "Employee" );

			Assertion.Assert( "Can run Imperative CEO Check!", !sensitiveClass.CanRunImperativeCEOCheck() );
			
			verifyMocks();	
		}
		[Test]
		public void NotAuthenticatedForImperativeCEOCheck()
		{
			mockIdentity.SetExpectedAuthenticationType( "NTLM" );
			mockIdentity.SetExpectedIsAuthenticated( false );
			mockIdentity.SetExpectedName( "Mr. Employee" );	
			
			mockPrincipal.SetExpectedIsInRoleCount(0);

			Assertion.Assert( "Authenticated!", !sensitiveClass.CanRunImperativeCEOCheck() );
			verifyMocks();
		}
		[Test]
		public void DeclarativeCEOCheck() 
		{
			mockIdentity.SetExpectedAuthenticationType( "NTLM" );
			mockIdentity.SetExpectedIsAuthenticated( true );
			mockIdentity.SetExpectedName( "Mr. CEO" );

			mockPrincipal.SetExpectedIsInRoleCount(1);
			mockPrincipal.AddExpectedRole( "CEO" );

			Assertion.Assert( "Cannot run Declarative CEO Check!", sensitiveClass.CanRunDeclarativeCEOCheck() );
			
			verifyMocks();
		}
		[Test]
		[ExpectedException(typeof(SecurityException))]
		public void CannotRunDeclarativeCEOCheck()
		{
			mockIdentity.SetExpectedAuthenticationType( "NTLM" );
			mockIdentity.SetExpectedIsAuthenticated( true );
			mockIdentity.SetExpectedName( "Mr. Employee" );

			mockPrincipal.SetExpectedIsInRoleCount(1);
			mockPrincipal.AddExpectedRole( "Employee" );

			try 
			{
				sensitiveClass.CanRunDeclarativeCEOCheck();
			} 
			finally
			{
				verifyMocks();
			}
			
			
		}
		[Test]
		[ExpectedException(typeof(SecurityException))]
		public void NotAuthenticatedForDeclarativeCEOCheck()
		{
			mockIdentity.SetExpectedAuthenticationType( "NTLM" );
			mockIdentity.SetExpectedIsAuthenticated( false );
			mockIdentity.SetExpectedName( "Mr. Employee" );	
			
			mockPrincipal.SetExpectedIsInRoleCount(0);

			try 
			{
				sensitiveClass.CanRunDeclarativeCEOCheck();
			}
			finally 
			{
				verifyMocks();
			}
		}
		private void verifyMocks()
		{
			mockIdentity.Verify();
			mockPrincipal.Verify();	
		}
	}
}
