context: //
  // NAntContrib
  // Copyright (C) 2002 Tomas Restrepo (tomasr@mvps.org)
  //
  // This library is free software; you can redistribute it and/or
  // modify it under the terms of the GNU Lesser General Public
  // License as published by the Free Software Foundation; either
  // version 2.1 of the License, or (at your option) any later version.
  //
  // This library is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  // Lesser General Public License for more details.
  //
  // You should have received a copy of the GNU Lesser General Public
  // License along with this library; if not, write to the Free Software
  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  //
  
  using System;
  using System.Collections;
  using System.Collections.Specialized;
  using System.IO;
  using System.Xml;
  
  using NUnit.Framework;
  
  using SourceSafeTypeLib;
  
  using NAnt.Core;
  
  using NAnt.Contrib.Tasks.SourceSafe;
  
  namespace Tests.NAnt.Contrib.Tasks.SourceSafe {
      /// <summary>
     /// VSS Get Task tests
     /// </summary>
      [TestFixture]
      public class GetTaskTests {
          string _workingFolder = "";
          string _localItemPath = "";
          string _localNormalItemPath = "";
          string _localReadOnlyItemPath = "";
          string _localReadOnlySubProjectPath = "";
          string _localReadOnlySubItemPath = "";
          string _localSubProjectPath = "";
          string _localSubItemPath = "";
  
          MockVssItem _project;
          MockVssItem _item;
          MockVssItem _alreadyGoneItem;
          MockVssItem _readOnlyItem;
          MockVssItem _readOnlySubProject;
          MockVssItem _readOnlySubItem;
          MockVssItem _subProject;
          MockVssItem _subItem;
          MockVssItem _normalItem;
          MockVssItem _normalItemDeleted;
  
          GetTask _getTask;
  
          [SetUp]
          public void Setup() {
              //create base folder for "project"'s local copy
              _workingFolder = Path.Combine(Path.GetTempPath(), "FROM_VSS");
              Directory.CreateDirectory(_workingFolder);
  
              //This item represents the base project item
              _project = new MockVssItem();
              _project.Name = "TEMPVSSPROJECT";
              _project.SetType((int) VSSItemType.VSSITEM_PROJECT);
              string localProjectPath = _workingFolder;
              Directory.CreateDirectory(localProjectPath);
  
              //a normal file item whose local copy is in the project's local folder;
              _normalItem = new MockVssItem();
              _normalItem.Name = "normalItem.txt";
              _normalItem.SetType((int) VSSItemType.VSSITEM_FILE);
              _normalItem.Deleted = false;
              _localNormalItemPath = Path.Combine(localProjectPath, _normalItem.Name);
              StreamWriter s = File.CreateText(_localNormalItemPath);
              s.Close();
  
              //a deleted file item that represents an earlier, deleted version of the normal file item
              _normalItemDeleted = new MockVssItem();
              _normalItemDeleted.Name = "normalItem.txt";
              _normalItemDeleted.SetType((int) VSSItemType.VSSITEM_FILE);
              _normalItemDeleted.Deleted = true;
  
              //a deleted file item whose local copy is located under the base project's local folder
              _item = new MockVssItem();
              _item.Name = "tempVSSItem.txt";
              _item.SetType((int) VSSItemType.VSSITEM_FILE);
              _item.Deleted = true;
              _localItemPath = Path.Combine(localProjectPath, _item.Name);
              s = File.CreateText(_localItemPath);
              s.Close();
  
              //a deleted file item with *no* local copy
              _alreadyGoneItem = new MockVssItem();
              _alreadyGoneItem.Name = "notthere.txt";
              _alreadyGoneItem.SetType((int) VSSItemType.VSSITEM_FILE);
              _alreadyGoneItem.Deleted = true;
  
              //a deleted file item whose local copy is located under the base project's local folder and read-only
              _readOnlyItem = new MockVssItem();
              _readOnlyItem.Name = "readOnlyTempVSSItem.txt";
              _readOnlyItem.SetType((int) VSSItemType.VSSITEM_FILE);
              _readOnlyItem.Deleted = true;
              _localReadOnlyItemPath = Path.Combine(localProjectPath, _readOnlyItem.Name);
              s = File.CreateText(_localReadOnlyItemPath);
              s.Close();
              File.SetAttributes(_localReadOnlyItemPath, FileAttributes.ReadOnly);
  
              //a deleted project item whose local copy is located under the base project's local folder and read-only
              _readOnlySubProject = new MockVssItem();
              _readOnlySubProject.Name = "READONLYSUBPROJECT";
              _readOnlySubProject.SetType((int) VSSItemType.VSSITEM_PROJECT);
              _readOnlySubProject.Deleted = true;
              _localReadOnlySubProjectPath = Path.Combine(localProjectPath, _readOnlySubProject.Name);
              Directory.CreateDirectory(_localReadOnlySubProjectPath);
              File.SetAttributes(_localReadOnlySubProjectPath, FileAttributes.ReadOnly);
  
              //a deleted file item whose local copy is located under the read-only sub project's local folder 
              //is itself read-only
              _readOnlySubItem = new MockVssItem();
              _readOnlySubItem.Name = "readOnlySubItem.txt";
              _readOnlySubItem.SetType((int) VSSItemType.VSSITEM_FILE);
              _readOnlySubItem.Deleted = true;
              _localReadOnlySubItemPath = Path.Combine(_localReadOnlySubProjectPath, _readOnlySubItem.Name);
              s = File.CreateText(_localReadOnlySubItemPath);
              s.Close();
              File.SetAttributes(_localReadOnlySubItemPath, FileAttributes.ReadOnly);
  
              //a deleted project item whose local copy is in the base project's local folder
              _subProject = new MockVssItem();
              _subProject.Name = "SUBPROJECT";
              _subProject.SetType((int) VSSItemType.VSSITEM_PROJECT);
              _subProject.Deleted = true;
              _localSubProjectPath = Path.Combine(localProjectPath, _subProject.Name);
              Directory.CreateDirectory(_localSubProjectPath);
  
              //a deleted file item whose local copy is in the sub-project's local folder
              _subItem = new MockVssItem();
              _subItem.Name = "tempVSSSubItem.txt";
              _subItem.SetType((int) VSSItemType.VSSITEM_FILE);
              _subItem.Deleted = true;
              _localSubItemPath = Path.Combine(_localSubProjectPath, _subItem.Name);
              s = File.CreateText(_localSubItemPath);
              s.Close();
  
              //add the sub file item to the sub project's items collection
              MockVssItems items = new MockVssItems();
              items.Add(_subItem);
              _subProject.SetItems(items);
  
              //add the read-only sub file item to read-only sub-project's items collection
              items = new MockVssItems();
              items.Add(_readOnlySubItem);
              _readOnlySubProject.SetItems(items);
  
              //create the instance of the GetTask that we will use in the tests
              _getTask = new GetTask();
              _getTask.Item = _project;
              _getTask.LocalPath = new DirectoryInfo(_workingFolder);
              _getTask.RemoveDeleted = true;
  
              //make the GetTask happy by giving it a dummy project file to reference
              XmlDocument doc = new XmlDocument();
              doc.LoadXml("<project name='test'/>");
              _getTask.Project = new Project(doc, Level.Info, 0);
          }
  
          [TearDown]
          public void Teardown() {
              if(File.Exists(_localReadOnlyItemPath)) {
                  File.SetAttributes(_localReadOnlyItemPath, FileAttributes.Normal);
              }
  
              if(Directory.Exists(_localReadOnlySubProjectPath)) {
                  File.SetAttributes(_localReadOnlySubProjectPath, FileAttributes.Normal);
              }
  
              if(File.Exists(_localReadOnlySubItemPath)) {
                  File.SetAttributes(_localReadOnlySubItemPath, FileAttributes.Normal);
              }
  
              Directory.Delete(_workingFolder, true);
          }
  
          /// <summary>
          /// Ensures items that are not marked deleted are left alone
          /// </summary>
          [Test]
          public void DeletionOfLocalFilesSkippedIfItemNotDeleted() {
              MockVssItems items = new MockVssItems();
              items.Add(_normalItem);
              _project.SetItems(items);
  
              _getTask.RemoveDeletedFromLocalImage();
  
              Assert.IsTrue(File.Exists(_localNormalItemPath), "Normal file should still exist");
          }
  
          /// <summary>
          /// This test ensures that items deleted and restored (i.e. an normal item with the same name as 
          /// a deleted item exists in the repository) are not deleted from the local image
          /// </summary>
          [Test]
          public void LeaveRestoredItemsInPlace() {
              MockVssItems items = new MockVssItems();
              items.Add(_normalItem);
              items.Add(_normalItemDeleted);
              _project.SetItems(items);
  
              _getTask.RemoveDeletedFromLocalImage();
  
              Assert.IsTrue(File.Exists(_localNormalItemPath), "Normal file should still exist");
          }
  
          /// <summary>
          /// Ensures that file items marked deleted in the project directory are removed
          /// </summary>
          [Test]
          public void DeletionOfLocalFiles() {
              MockVssItems items = new MockVssItems();
              items.Add(_item);
              _project.SetItems(items);
  
              _item.Deleted = false;
              _getTask.RemoveDeletedFromLocalImage();
              Assert.IsTrue(File.Exists(_localItemPath), "deleted file should be there");
  
              _item.Deleted = true;
              _getTask.RemoveDeletedFromLocalImage();
              Assert.IsFalse(File.Exists(_localItemPath), "deleted file should be gone");
  
          }
  
          /// <summary>
          /// Ensures that project items marked deleted in the project directory are removed
          /// </summary>
          [Test]
          public void DeletionOfLocalProjects() {
              MockVssItems items = new MockVssItems();
              items.Add(_subProject);
              _project.SetItems(items);
  
              _subProject.Deleted = false;
              _getTask.RemoveDeletedFromLocalImage();
              Assert.IsTrue(Directory.Exists(_localSubProjectPath), "deleted folder should be there");
  
              _subProject.Deleted = true;
              _getTask.RemoveDeletedFromLocalImage();
              Assert.IsFalse(Directory.Exists(_localSubProjectPath), "deleted folder should be gone");
          }
  
          [Test]
          public void RecursiveIsFalseSubProjectsIgnored() {
              MockVssItems items = new MockVssItems();
              items.Add(_item);
              items.Add(_subProject);
              _project.SetItems(items);
  
              _subProject.Deleted = false;
              _getTask.Recursive = false;
  
              Assert.IsTrue(File.Exists(_localItemPath), "file should exist");
              Assert.IsTrue(File.Exists(_localSubItemPath), "file should exist");
  
              _getTask.RemoveDeletedFromLocalImage();
  
              Assert.IsFalse(File.Exists(_localItemPath), "this file should be gone");
              Assert.IsTrue(File.Exists(_localSubItemPath), "this file should still be there");
          }
  
          [Test]
          public void RecursiveIsTrueSubProjectsIncluded() {
              MockVssItems items = new MockVssItems();
              items.Add(_item);
              items.Add(_subProject);
              _project.SetItems(items);
  
              _subProject.Deleted = false;
              _getTask.Recursive = true;
  
              Assert.IsTrue(File.Exists(_localItemPath), "file should exist");
              Assert.IsTrue(File.Exists(_localSubItemPath), "file should also exist");
  
              _getTask.RemoveDeletedFromLocalImage();
  
              Assert.IsFalse(File.Exists(_localItemPath), "this file should be gone");
              Assert.IsFalse(File.Exists(_localSubItemPath), "this file should also be gone");
          }
  
          [Test]
          public void HandleReadOnlyFiles() {
              MockVssItems items = new MockVssItems();
              items.Add(_readOnlyItem);
              _project.SetItems(items);
  
              Assert.IsTrue(File.Exists(_localReadOnlyItemPath), "file should exist");
  
              _getTask.RemoveDeletedFromLocalImage();
  
              Assert.IsFalse(File.Exists(_localReadOnlyItemPath), "this file should be gone");
          }
  
          [Test]
          public void HandleReadOnlyFolders() {
              MockVssItems items = new MockVssItems();
              items.Add(_readOnlySubProject);
              _project.SetItems(items);
  
              Assert.IsTrue(Directory.Exists(_localReadOnlySubProjectPath), "folder should exist");
  
              _getTask.RemoveDeletedFromLocalImage();
  
              Assert.IsFalse(Directory.Exists(_localReadOnlySubProjectPath), "this file should be gone");
          }
  
          /// <summary>
          /// Ensures that already removed items do not throw an exception
          /// </summary>
          [Test]
          public void IgnoreAlreadyRemovedItems() {
              MockVssItems items = new MockVssItems();
              items.Add(_alreadyGoneItem);
              _project.SetItems(items);
  
              _getTask.RemoveDeletedFromLocalImage();
          }
  
          /// Verifies that items deleted are marked deleted
          /// </summary>
          [Test]
          public void BuildDeletedTableDoesIncludeDeletedItems() {
              MockVssItem deleted = new MockVssItem();
              deleted.Name = "deleted";
              deleted.Deleted = true;
  
              MockVssItems items = new MockVssItems();
              items.Add(deleted);
  
              Hashtable table = _getTask.BuildDeletedTable(items);
  
              Assert.IsTrue((bool) table[deleted.Name], "deleted items should be deleted");
          }
  
          /// <summary>
          /// Verifies that items never deleted are not marked deleted
          /// </summary>
          [Test]
          public void BuildDeletedTableDoesNotIncludeRegularItems() {
  
gt:             MockVssItem regular = new MockVssItem();