// Copyright (c) 2008, NTT DATA Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Text;
using System.Collections.Generic;
using TERASOLUNA.Fw.Client.Configuration.View;
using System.Xml;
using TERASOLUNA.Fw.Client.Configuration;
using System.Configuration;
using TERASOLUNA.Fw.Common.Configuration;
using TERASOLUNA.Fw.Utlib.Logging;
using TERASOLUNA.Fw.Common.Logging;
using TERASOLUNA.Fw.Common;
using System.Xml.Schema;
using System.IO;
namespace TERASOLUNA.Fw.ClientUT.Configuration.View
{
    /// <summary>
    ///TERASOLUNA.Fw.Client.Configuration.View.ViewConfigurationSection のテスト クラスです。すべての
    ///TERASOLUNA.Fw.Client.Configuration.View.ViewConfigurationSection 単体テストをここに含めます
    ///</summary>
    [TestClass()]
    public class ViewConfigurationSectionTest
    {


        private TestContext testContextInstance;

        ///<summary>
        /// CreateViewElementsTest01で利用するテストデータです。
        ///</summary>
        private const string CONFIG_FILE_NAME_01 = "ViewConfiguSection_ViewConfigSection01.config";

        ///<summary>
        /// CreateViewElementsTest02で利用するテストデータです。
        ///</summary>
        private const string CONFIG_FILE_NAME_02 = "ViewConfiguSection_ViewConfigSection02.config";

        ///<summary>
        /// CreateViewElementsTest04で利用するテストデータです。
        ///</summary>
        private const string CONFIG_FILE_NAME_04 = "ViewConfiguSection_ViewConfigSection04.config";

        ///<summary>
        /// CreateViewElementsTest05で利用するテストデータです。
        ///</summary>
        private const string CONFIG_FILE_NAME_05 = "ViewConfiguSection_ViewConfigSection05.config";

        ///<summary>
        /// CreateViewElementsTest06で利用するテストデータです。
        ///</summary>
        private const string CONFIG_FILE_NAME_06 = "ViewConfiguSection_ViewConfigSection06.config";

        ///<summary>
        /// CreateViewElementsTest07で利用するテストデータです。
        ///</summary>
        private const string CONFIG_FILE_NAME_07 = "ViewConfiguSection_ViewConfigSection07.config";

        ///<summary>
        /// CreateViewElementsTest08で利用するテストデータです。
        ///</summary>
        private const string CONFIG_FILE_NAME_08 = "ViewConfiguSection_ViewConfigSection08.config";

        ///<summary>
        /// CreateViewElementsTest09で利用するテストデータです。
        ///</summary>
        private const string CONFIG_FILE_NAME_09 = "ViewConfiguSection_ViewConfigSection09.config";

        ///<summary>
        /// CreateViewElementsTest10で利用するテストデータです。
        ///</summary>
        private const string CONFIG_FILE_NAME_10 = "ViewConfiguSection_ViewConfigSection10.config";

        ///<summary>
        /// CreateViewElementsTest11で利用するテストデータです。
        ///</summary>
        private const string CONFIG_FILE_NAME_11 = "ViewConfiguSection_ViewConfigSection11.config";

        /// <summary>
        ///現在のテストの実行についての情報および機能を
        ///提供するテスト コンテキストを取得または設定します。
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }
        #region 追加のテスト属性
        // 
        //テストを作成するときに、次の追加属性を使用することができます:
        //
        //クラスの最初のテストを実行する前にコードを実行するには、ClassInitialize を使用
        //
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //クラスのすべてのテストを実行した後にコードを実行するには、ClassCleanup を使用
        //
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //各テストを実行する前にコードを実行するには、TestInitialize を使用
        //
        [TestInitialize()]
        public void MyTestInitialize()
        {
            LogUTUtil.Clear();
        }
        //
        //各テストを実行した後にコードを実行するには、TestCleanup を使用
        //
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        ///<summary>
        /// CreateViewElements () のテスト
        ///</summary>
        ///<remarks>
        /// 構成ファイル、外部設定ファイルが複数存在し、スキーマに即している場合
        /// 外部ファイルの情報がフィールドViewCollectionに設定されることを確認するテスト。
        ///</remarks>
        [TestMethod()]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewConfigSection01.config")]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewExternal01.config")]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewExternal02.config")]
        public void CreateViewElementsTest01()
        {
            // 準備
            ViewConfigurationSection target =
                ConfigTestHelper.GetViewConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_01);

            // 実行
            target.CreateViewElements();

            // 検証
            ViewCollection actualCollection = target.ViewCollection;
            Assert.IsNotNull(actualCollection);
            Assert.AreEqual(3, actualCollection.Count);
            ViewElement actualElement1 = actualCollection[0];
            ViewElement actualElement2 = actualCollection[1];
            ViewElement actualElement3 = actualCollection[2];

            Assert.AreEqual("registerView", actualElement1.Id);
            Assert.AreEqual("ClientPrototypeApp.RegisterForm, ClientPrototypeApp", actualElement1.Type);
            Assert.AreEqual("chargeUserFormView", actualElement2.Id);
            Assert.AreEqual("ClientPrototypeApp.ChargeUserForm, ClientPrototypeApp", actualElement2.Type);
            Assert.AreEqual("searchView", actualElement3.Id);
            Assert.AreEqual("ClientPrototypeApp.TourInfoSearch, ClientPrototypeApp", actualElement3.Type);

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(ViewConfigurationSection), LogLevel.INFO));

        }

        ///<summary>
        /// CreateViewElements () のテスト
        ///</summary>
        ///<remarks>
        /// 構成ファイル、外部設定ファイルがひとつだけ存在し、スキーマに即している場合
        /// 外部ファイルの情報がフィールドViewCollectionに設定されることを確認するテスト。
        ///</remarks>
        [TestMethod()]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewConfigSection02.config")]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewExternal01.config")]
        public void CreateViewElementsTest02()
        {
            // 準備
            ViewConfigurationSection target =
                ConfigTestHelper.GetViewConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_02);

            // 実行
            target.CreateViewElements();

            // 検証
            ViewCollection actualCollection = target.ViewCollection;
            Assert.IsNotNull(actualCollection);
            Assert.AreEqual(2, actualCollection.Count);
            ViewElement actualElement1 = actualCollection[0];
            ViewElement actualElement2 = actualCollection[1];

            Assert.AreEqual("registerView", actualElement1.Id);
            Assert.AreEqual("ClientPrototypeApp.RegisterForm, ClientPrototypeApp", actualElement1.Type);
            Assert.AreEqual("chargeUserFormView", actualElement2.Id);
            Assert.AreEqual("ClientPrototypeApp.ChargeUserForm, ClientPrototypeApp", actualElement2.Type);

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(ViewConfigurationSection), LogLevel.INFO));
        }

        ///<summary>
        /// CreateViewElements () のテスト
        ///</summary>
        ///<remarks>
        /// 構成ファイルを指定しない場合、ConfigurationErrorsExceptionがスローされることを確認するテスト。
        ///</remarks>
        [TestMethod()]
        public void CreateViewElementsTest03()
        {
            // 準備
            ViewConfigurationSection target = new ViewConfigurationSection();
            FilesCollection files = target.Files;
            string sectionName = TERASOLUNA_Fw_Client_Configuration_View_ViewConfigurationSectionAccessor.SECTION_NAME;
            
            // 実行
            try
            {
                target.CreateViewElements();
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (ConfigurationErrorsException e)
            {
                // 成功
                string message = MessageManager.GetMessage("E_CONFIGURATION_INVALID_CUSTOM_SECTION_HANDLER", sectionName);
                Assert.AreEqual(message, e.Message); 
            }

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(ViewConfigurationSection), LogLevel.INFO));

        }

        ///<summary>
        /// CreateViewElements () のテスト
        ///</summary>
        ///<remarks>
        /// 構成ファイルにviewConfiguration要素が存在しない場合
        /// ConfigurationErrorsExceptionがスローされることを確認するテスト。
        ///</remarks>
        [TestMethod()]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewConfigSection04.config")]
        public void CreateViewElementsTest04()
        {
            // 準備
            ViewConfigurationSection target =
                ConfigTestHelper.GetViewConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_04);
            FilesCollection files = target.Files;
            string sectionName = TERASOLUNA_Fw_Client_Configuration_View_ViewConfigurationSectionAccessor.SECTION_NAME;
 
            // 実行
            try
            {
                target.CreateViewElements();
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (ConfigurationErrorsException e) 
            {
                // 成功
                string message = MessageManager.GetMessage("E_CONFIGURATION_INVALID_CUSTOM_SECTION_HANDLER", sectionName);
                Assert.AreEqual(message, e.Message);
            }

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(ViewConfigurationSection), LogLevel.INFO));

        }

        ///<summary>
        /// CreateViewElements () のテスト
        ///</summary>
        ///<remarks>
        /// 構成ファイルにfile要素が存在しない場合
        /// ConfigurationErrorsExceptionがスローされることを確認するテスト。
        ///</remarks>
        [TestMethod()]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewConfigSection05.config")]
        public void CreateViewElementsTest05()
        {
            // 準備
            ViewConfigurationSection target =
                ConfigTestHelper.GetViewConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_05);
            string sectionName = TERASOLUNA_Fw_Client_Configuration_View_ViewConfigurationSectionAccessor.SECTION_NAME;

            // 実行
            try
            {
                target.CreateViewElements();
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (ConfigurationErrorsException e)
            {
                // 成功
                string message = MessageManager.GetMessage("E_CONFIGURATION_INVALID_CUSTOM_SECTION_HANDLER", sectionName);
                Assert.AreEqual(message, e.Message);
            }

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(ViewConfigurationSection), LogLevel.INFO));

        }

        ///<summary>
        /// CreateViewElements () のテスト
        ///</summary>
        ///<remarks>
        /// 構成ファイル記述されたfile要素が存在しないファイルを指定している場合
        /// ConfigurationErrorsExceptionがスローされることを確認するテスト。
        ///</remarks>
        [TestMethod()]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewConfigSection06.config")]
        public void CreateViewElementsTest06()
        {
            // 準備
            ViewConfigurationSection target =
                ConfigTestHelper.GetViewConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_06);
            FilesCollection files = target.Files;
            string sectionName = TERASOLUNA_Fw_Client_Configuration_View_ViewConfigurationSectionAccessor.SECTION_NAME;

            // 実行
            try
            {
                target.CreateViewElements();
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (ConfigurationErrorsException e)
            {
                // 成功
                string message = MessageManager.GetMessage("E_CONFIGURATION_EXTERNAL_CONFIG_LOAD_FAILED", sectionName, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, files[0].Path));
                Assert.AreEqual(message, e.Message);
                Assert.IsInstanceOfType(e.InnerException, typeof(IOException));
            }

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(ViewConfigurationSection), LogLevel.INFO));

        }

        ///<summary>
        /// CreateViewElements () のテスト
        ///</summary>
        ///<remarks>
        /// 外部設定ファイルにスキーマ違反(ID一意制約違反)が存在する場合
        /// ConfigurationErrorsExceptionがスローされることを確認するテスト。
        ///</remarks>
        [TestMethod()]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewConfigSection07.config")]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewExternal03.config")]
        public void CreateViewElementsTest07()
        {
            // 準備
            ViewConfigurationSection target =
                ConfigTestHelper.GetViewConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_07);
            FilesCollection files = target.Files;
            string sectionName = TERASOLUNA_Fw_Client_Configuration_View_ViewConfigurationSectionAccessor.SECTION_NAME;

            // 実行
            try
            {
                target.CreateViewElements();
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (ConfigurationErrorsException e)
            {
                string message = MessageManager.GetMessage("E_CONFIGURATION_INVALID_EXTERNAL_CONFIG_FILE", sectionName, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, files[0].Path));
                Assert.AreEqual(message, e.Message);
                Assert.IsInstanceOfType(e.InnerException, typeof(XmlSchemaException));
            }

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(ViewConfigurationSection), LogLevel.INFO));
        }

        ///<summary>
        /// CreateViewElements () のテスト
        ///</summary>
        ///<remarks>
        /// 外部設定ファイルにスキーマ違反(ID属性なし)が存在する場合
        /// ConfigurationErrorsExceptionがスローされることを確認するテスト。
        ///</remarks>
        [TestMethod()]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewConfigSection08.config")]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewExternal04.config")]
        public void CreateViewElementsTest08()
        {
            // 準備
            ViewConfigurationSection target =
                ConfigTestHelper.GetViewConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_08);
            FilesCollection files = target.Files;
            string sectionName = TERASOLUNA_Fw_Client_Configuration_View_ViewConfigurationSectionAccessor.SECTION_NAME;
            
            // 実行
            try
            {
                target.CreateViewElements();
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (ConfigurationErrorsException e)
            {
                string message = MessageManager.GetMessage("E_CONFIGURATION_INVALID_EXTERNAL_CONFIG_FILE", sectionName, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, files[0].Path));
                Assert.AreEqual(message, e.Message);
                Assert.IsInstanceOfType(e.InnerException, typeof(XmlSchemaException));
            }

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(ViewConfigurationSection), LogLevel.INFO));

        }

        ///<summary>
        /// CreateViewElements () のテスト
        ///</summary>
        ///<remarks>
        /// 外部設定ファイルにスキーマ違反(type属性なし)が存在する場合
        /// ConfigurationErrorsExceptionがスローされることを確認するテスト。
        ///</remarks>
        [TestMethod()]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewConfigSection09.config")]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewExternal05.config")]
        public void CreateViewElementsTest09()
        {
            // 準備
            ViewConfigurationSection target =
                ConfigTestHelper.GetViewConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_09);
            FilesCollection files = target.Files;
            string sectionName = TERASOLUNA_Fw_Client_Configuration_View_ViewConfigurationSectionAccessor.SECTION_NAME;
            
            // 実行
            try
            {
                target.CreateViewElements();
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (ConfigurationErrorsException e)
            {
                string message = MessageManager.GetMessage("E_CONFIGURATION_INVALID_EXTERNAL_CONFIG_FILE", sectionName, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, files[0].Path));
                Assert.AreEqual(message, e.Message);
                Assert.IsInstanceOfType(e.InnerException, typeof(XmlSchemaException));
            }

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(ViewConfigurationSection), LogLevel.INFO));

        }

        ///<summary>
        /// CreateViewElements () のテスト
        ///</summary>
        ///<remarks>
        /// 外部設定ファイルにスキーマ違反(View最小出現数違反)が存在する場合
        /// ConfigurationErrorsExceptionがスローされることを確認するテスト。
        ///</remarks>
        [TestMethod()]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewConfigSection10.config")]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewExternal06.config")]
        public void CreateViewElementsTest10()
        {
            // 準備
            ViewConfigurationSection target =
                ConfigTestHelper.GetViewConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_10);
            FilesCollection files = target.Files;
            string sectionName = TERASOLUNA_Fw_Client_Configuration_View_ViewConfigurationSectionAccessor.SECTION_NAME;

            // 実行
            try
            {
                target.CreateViewElements();
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (ConfigurationErrorsException e)
            {
                string message = MessageManager.GetMessage("E_CONFIGURATION_EXTERNAL_CONFIG_LOAD_FAILED", sectionName, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, files[0].Path));
                Assert.AreEqual(message, e.Message);
                Assert.IsInstanceOfType(e.InnerException, typeof(IOException));
            }

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(ViewConfigurationSection), LogLevel.INFO));

        }

        ///<summary>
        /// CreateViewElements () のテスト
        ///</summary>
        ///<remarks>
        /// 外部設定ファイルのid、typeに空文字が設定されていた場合
        /// ConfigurationErrorsExceptionが発生することを確認するテスト。
        ///</remarks>
        [TestMethod()]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewConfigSection11.config")]
        [DeploymentItem(@"Configuration\View\ViewConfigurationSectionTestData\ViewConfiguSection_ViewExternal07.config")]
        public void CreateViewElementsTest11()
        {
            // 準備
            ViewConfigurationSection target =
                ConfigTestHelper.GetViewConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_11);
            FilesCollection files = target.Files;
            string sectionName = TERASOLUNA_Fw_Client_Configuration_View_ViewConfigurationSectionAccessor.SECTION_NAME;

            // 実行
            try
            {
                target.CreateViewElements();
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (ConfigurationErrorsException e)
            {
                // 成功
                string message = MessageManager.GetMessage("E_CONFIGURATION_EXTERNAL_CONFIG_LOAD_FAILED", sectionName, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, files[0].Path));
                Assert.AreEqual(message, e.Message);
                Assert.IsInstanceOfType(e.InnerException, typeof(IOException));
            }

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(ViewConfigurationSection), LogLevel.INFO));

        }

        ///<summary>
        /// Files のテスト
        ///</summary>
        ///<remarks>
        /// フィールドFilesが設定されていることを確認するテスト。
        ///</remarks>
        [TestMethod()]
        public void FilesTest01()
        {
            ViewConfigurationSection target = new ViewConfigurationSection();
            FilesCollection actual = target.Files;
            Assert.IsNotNull(actual);

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(ViewConfigurationSection), LogLevel.INFO));
        }

        ///<summary>
        /// ViewCollection のテスト
        ///</summary>
        ///<remarks>
        /// フィールドViewCollectionが設定されていることを確認するテスト。
        ///</remarks>
        [TestMethod()]
        public void ViewCollectionTest01()
        {
            ViewConfigurationSection target = new ViewConfigurationSection();
            ViewCollection actual = target.ViewCollection;
            Assert.IsNotNull(actual);

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(ViewConfigurationSection), LogLevel.INFO));
        }

        ///<summary>
        /// ViewConfigurationSection () のテスト
        ///</summary>
        ///<remarks>
        /// デフォルトコンストラクタを実行して例外が発生しないことを確認するテスト。
        ///</remarks>
        [TestMethod()]
        public void ConstructorTest01()
        {
            ViewConfigurationSection target = new ViewConfigurationSection();
            Assert.IsNotNull(target);

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(ViewConfigurationSection), LogLevel.INFO));
        }

    }

}
