// 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 System.IO;
using TERASOLUNA.Fw.Web.Controller;
using TERASOLUNA.Fw.WebUT;
using TERASOLUNA.Fw.Utlib.Logging;
using TERASOLUNA.Fw.Common.Logging;
using TERASOLUNA.Fw.Common;

namespace TERASOLUNA.Fw.WebUT.Controller
{
    /// <summary>
    /// TERASOLUNA.Fw.Web.Multipart.MultipartTextItem のテスト クラスです。
    ///</summary>

    [TestClass()]
    public class MultipartTextItemTest
    {

        private TestContext testContextInstance;

        // テスト対象となるクラス
        private MultipartTextItem target = null;

        // boudary[文字列 : boundary]
        private static readonly string BOUNDARY = "boundary";

        // エンコード[UTF-8]
        private static readonly Encoding ENCODING = new UTF8Encoding();

        /// <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>
        /// MultipartTextItem (string, Stream, IDictionary&lt;string,string&gt;, Encoding) のテスト
        ///</summary>
        ///<remarks>
        /// partStreamに区切り文字が存在する場合、
        /// 正常に動作することを確認するテスト。
        ///</remarks>

        [TestMethod()]
        [DeploymentItem(@"Controller\Files\MultipartTextItem.txt")]
        public void ConstructorTest01()
        {
            // 準備
            Stream fs = new FileStream(@"MultipartTextItem.txt", FileMode.Open, FileAccess.Read);

            Stream partStream = fs;

            System.Collections.Generic.IDictionary<string, string> headerList = new Dictionary<string, string>();
            headerList.Add("CONTENT-DISPOSITION", "form-data; name=text1");
            headerList.Add("content-type", "application/x-www-form-urlencoded");
            headerList.Add("content-part", "MultipartTextItem");

            // 実行
            target = new MultipartTextItem(BOUNDARY, partStream, headerList, ENCODING);

            string expectedValue = "単体試験";

            TERASOLUNA.Fw.WebUT.TERASOLUNA_Fw_Web_Controller_MultipartTextItemAccessor accessor =
                new TERASOLUNA.Fw.WebUT.TERASOLUNA_Fw_Web_Controller_MultipartTextItemAccessor(target);

            // 検証
            Assert.AreEqual(expectedValue, accessor._text);

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

        }

        /// <summary>
        ///MultipartTextItem (string, Stream, IDictionary&lt;string,string&gt;, Encoding) のテスト
        ///</summary>
        ///<remarks>
        /// partStreamがnullの場合、
        /// 例外(ArgumentNullException)が発生することを確認するテスト。
        ///</remarks>

        [TestMethod()]
        public void ConstructorTest02()
        {
            // 準備
            Stream partStream = null;

            System.Collections.Generic.IDictionary<string, string> headerList = new Dictionary<string, string>();
            headerList.Add("CONTENT-DISPOSITION", "form-data; name=text1");
            headerList.Add("content-type", "application/x-www-form-urlencoded");
            headerList.Add("content-part", "MultipartTextItem");

            // 実行
            try
            {
                // 失敗
                MultipartTextItem target = new MultipartTextItem(BOUNDARY, partStream, headerList, ENCODING);
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (ArgumentNullException ex)
            {
                // 成功
                Assert.AreEqual("partStream", ex.ParamName);
            }
            catch (Exception e)
            {
                // 失敗
                Assert.Fail("予期せぬエラーです。" + e.ToString());
            }

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

        /// <summary>
        /// MultipartTextItem (string, Stream, IDictionary&lt;string,string&gt;, Encoding) のテスト
        ///</summary>
        ///<remarks>
        /// MultipartTextItem.txtに区切り文字が存在しない場合、
        /// InvalidRequestExceptionが発生することを確認するテスト。
        ///</remarks>

        [TestMethod()]
        [DeploymentItem(@"Controller\Files\MultipartTextItem2.txt")]
        public void ConstructorTest03()
        {
            // 準備
            Stream fs = new FileStream(@"MultipartTextItem2.txt", FileMode.Open, FileAccess.Read);

            Stream partStream = fs;

            System.Collections.Generic.IDictionary<string, string> headerList = new Dictionary<string, string>();
            headerList.Add("CONTENT-DISPOSITION", "form-data; name=text1");
            headerList.Add("content-type", "application/x-www-form-urlencoded");
            headerList.Add("content-part", "MultipartTextItem");

            // 実行
            try
            {
                // 失敗
                MultipartTextItem target = new MultipartTextItem(BOUNDARY, partStream, headerList, ENCODING);
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (InvalidRequestException ex)
            {
                // 成功
                Assert.AreEqual(typeof(InvalidRequestException).Name, ex.GetType().Name);
                Assert.AreEqual(MessageManager.GetMessage("E_NOT_FOUND_ENDCODE"), ex.Message);

            }
            catch (Exception e)
            {
                // 失敗
                Assert.Fail("予期せぬエラーです。" + e.ToString());
            }

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

        }


        /// <summary>
        /// Text のテスト
        ///</summary>
        ///<remarks>
        /// 要素数3のインスタンスを設定し、nullを設定した場合、
        /// nullの取得を確認するテスト
        ///</remarks>
        [TestMethod()]
        [DeploymentItem(@"Controller\Files\MultipartTextItem.txt")]
        public void TextTest01()
        {
            // 準備
            Stream fs = new FileStream(@"MultipartTextItem.txt", FileMode.Open, FileAccess.Read);

            Stream partStream = fs;

            System.Collections.Generic.IDictionary<string, string> headerList = new Dictionary<string, string>();
            headerList.Add("CONTENT-DISPOSITION", "form-data; name=text1");
            headerList.Add("content-type", "application/x-www-form-urlencoded");
            headerList.Add("content-part", "MultipartTextItem");

            // 実行
            MultipartTextItem target = new MultipartTextItem(BOUNDARY, partStream, headerList, ENCODING);

            TERASOLUNA.Fw.WebUT.TERASOLUNA_Fw_Web_Controller_MultipartTextItemAccessor accessor = new TERASOLUNA.Fw.WebUT.TERASOLUNA_Fw_Web_Controller_MultipartTextItemAccessor(target);
            accessor._text = null;

            // 検証
            Assert.IsNull(target.Text);

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

        }


        /// <summary>
        /// Text のテスト
        ///</summary>
        ///<remarks>
        /// 要素数3のインスタンスを設定し、空文字列を設定した場合、
        /// 空文字列の取得を確認するテスト
        ///</remarks>
        [TestMethod()]
        [DeploymentItem(@"Controller\Files\MultipartTextItem.txt")]
        public void TextTest02()
        {
            // 準備
            Stream fs = new FileStream(@"MultipartTextItem.txt", FileMode.Open, FileAccess.Read);

            Stream partStream = fs;

            System.Collections.Generic.IDictionary<string, string> headerList = new Dictionary<string, string>();
            headerList.Add("CONTENT-DISPOSITION", "form-data; name=text1");
            headerList.Add("content-type", "application/x-www-form-urlencoded");
            headerList.Add("content-part", "MultipartTextItem");

            // 実行
            MultipartTextItem target = new MultipartTextItem(BOUNDARY, partStream, headerList, ENCODING);

            TERASOLUNA.Fw.WebUT.TERASOLUNA_Fw_Web_Controller_MultipartTextItemAccessor accessor = new TERASOLUNA.Fw.WebUT.TERASOLUNA_Fw_Web_Controller_MultipartTextItemAccessor(target);
            accessor._text = "";

            // 検証
            Assert.AreEqual(accessor._text, target.Text);

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

        }


        /// <summary>
        /// Textのテスト
        ///</summary>
        ///<remarks>
        /// 要素数3のインスタンスを設定し、半角文字列(空文字列でない)を設定した合、
        /// 半角文字列(空文字列でない)の取得を確認するテスト
        ///</remarks>
        [TestMethod()]
        [DeploymentItem(@"Controller\Files\MultipartTextItem.txt")]
        public void TextTest03()
        {
            // 検証
            Stream fs = new FileStream(@"MultipartTextItem.txt", FileMode.Open, FileAccess.Read);

            Stream partStream = fs;

            System.Collections.Generic.IDictionary<string, string> headerList = new Dictionary<string, string>();
            headerList.Add("CONTENT-DISPOSITION", "form-data; name=text1");
            headerList.Add("content-type", "application/x-www-form-urlencoded");
            headerList.Add("content-part", "MultipartTextItem");

            // 実行
            MultipartTextItem target = new MultipartTextItem(BOUNDARY, partStream, headerList, ENCODING);
            TERASOLUNA.Fw.WebUT.TERASOLUNA_Fw_Web_Controller_MultipartTextItemAccessor accessor = new TERASOLUNA.Fw.WebUT.TERASOLUNA_Fw_Web_Controller_MultipartTextItemAccessor(target);
            accessor._text = "hoge";

            // 検証
            Assert.AreEqual(accessor._text, target.Text);

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

        }


        /// <summary>
        /// Text のテスト
        ///</summary>
        ///<remarks>
        /// 要素数3のインスタンスを設定し、全角文字列(空文字列でない)を設定した場合、
        /// 全角文字列(空文字列でない)の取得を確認するテスト
        ///</remarks>
        [TestMethod()]
        [DeploymentItem(@"Controller\Files\MultipartTextItem.txt")]
        public void TextTest04()
        {
            // 準備
            Stream fs = new FileStream(@"MultipartTextItem.txt", FileMode.Open, FileAccess.Read);

            Stream partStream = fs;

            System.Collections.Generic.IDictionary<string, string> headerList = new Dictionary<string, string>();
            headerList.Add("CONTENT-DISPOSITION", "form-data; name=text1");
            headerList.Add("content-type", "application/x-www-form-urlencoded");
            headerList.Add("content-part", "MultipartTextItem");

            // 実行
            MultipartTextItem target = new MultipartTextItem(BOUNDARY, partStream, headerList, ENCODING);
            TERASOLUNA.Fw.WebUT.TERASOLUNA_Fw_Web_Controller_MultipartTextItemAccessor accessor = new TERASOLUNA.Fw.WebUT.TERASOLUNA_Fw_Web_Controller_MultipartTextItemAccessor(target);
            accessor._text = "単体試験";

            // 検証
            Assert.AreEqual(accessor._text, target.Text);

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

        }


        /// <summary>
        /// Dispose () のテスト
        /// </summary>
        /// <remarks>
        /// 実行できるかどうか確認するテスト
        /// </remarks>
        [TestMethod()]
        [DeploymentItem(@"Controller\Files\MultipartTextItem.txt")]
        public void DisposeTest()
        {
            // 準備
            Stream fs = new FileStream(@"MultipartTextItem.txt", FileMode.Open, FileAccess.Read);

            Stream partStream = fs;

            System.Collections.Generic.IDictionary<string, string> headerList = new Dictionary<string, string>();
            headerList.Add("CONTENT-DISPOSITION", "form-data; name=text1");
            headerList.Add("content-type", "application/x-www-form-urlencoded");
            headerList.Add("content-part", "MultipartTextItem");

            MultipartTextItem target = new MultipartTextItem(BOUNDARY, partStream, headerList, ENCODING);

            // 実行
            target.Dispose();

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

        }

        /// <summary>
        /// IsText のテスト
        ///</summary>
        ///<remarks>
        /// 要素数3のインスタンスを設定し、全角文字列(空文字列でない)を設定した場合、
        /// 全角文字列(空文字列でない)の取得を確認するテスト
        ///</remarks>
        [TestMethod()]
        [DeploymentItem(@"Controller\Files\MultipartTextItem.txt")]
        public void IsTextTest()
        {
            // 準備

            Stream fs = new FileStream(@"MultipartTextItem.txt", FileMode.Open, FileAccess.Read);

            Stream partStream = fs;

            System.Collections.Generic.IDictionary<string, string> headerList = new Dictionary<string, string>();
            headerList.Add("CONTENT-DISPOSITION", "form-data; name=text1");
            headerList.Add("content-type", "application/x-www-form-urlencoded");
            headerList.Add("content-part", "MultipartTextItem");

            // 実行
            MultipartTextItem target = new MultipartTextItem(BOUNDARY, partStream, headerList, ENCODING);

            // 検証
            Assert.IsTrue(target.IsText);

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

        }
    }
}
