<commit_before>require "spec_helper"
require "timeout"

describe "paperclip-storage-ftp", :integration => true do

  before(:all) do
    require "support/integration/ftp_server"
    require "support/integration/user"
    FtpServer.start
  end

  before(:each) do
    FtpServer.clear
  end

  let(:file) { File.new(File.expand_path("../support/integration/avatar.jpg", __FILE__), "rb") }
  let(:user) { User.new }

  let(:uploaded_file_server1)         { FtpServer::USER1_PATH + "/original/avatar.jpg" }
  let(:uploaded_file_server1_medium)  { FtpServer::USER1_PATH + "/medium/avatar.jpg"   }
  let(:uploaded_file_server1_thumb)   { FtpServer::USER1_PATH + "/thumb/avatar.jpg"    }
  let(:uploaded_file_server2)         { FtpServer::USER2_PATH + "/original/avatar.jpg" }
  let(:uploaded_file_server2_medium)  { FtpServer::USER2_PATH + "/medium/avatar.jpg"   }
  let(:uploaded_file_server2_thumb)   { FtpServer::USER2_PATH + "/thumb/avatar.jpg"    }

  it "stores the attachment on the ftp servers" do
    user.avatar = file
    user.save!

    File.exists?(uploaded_file_server1).should be true
    File.exists?(uploaded_file_server1_medium).should be true
    File.exists?(uploaded_file_server1_thumb).should be true
    File.exists?(uploaded_file_server2).should be true
    File.exists?(uploaded_file_server2_medium).should be true
    File.exists?(uploaded_file_server2_thumb).should be true

    file.size.should == File.size(uploaded_file_server1)
    file.size.should == File.size(uploaded_file_server2)
  end

  it "deletes an attachment from the ftp servers" do
    user.avatar = file
    user.save!

    user.destroy

    File.exists?(uploaded_file_server1).should be false
    File.exists?(uploaded_file_server1_medium).should be false
    File.exists?(uploaded_file_server1_thumb).should be false
    Dir.exists?(File.dirname(uploaded_file_server1)).should be false

    File.exists?(uploaded_file_server2).should be false
    File.exists?(uploaded_file_server2_medium).should be false
    File.exists?(uploaded_file_server2_thumb).should be false
    Dir.exists?(File.dirname(uploaded_file_server2)).should be false
  end

  it "survives temporarily closed ftp connections" do
    user.avatar = file
    user.save!

    user.avatar = nil
    user.save!

    FtpServer.restart

    user.avatar = file
    user.save!

    File.exists?(uploaded_file_server1).should be true
    File.exists?(uploaded_file_server2).should be true
  end

  it "allows ignoring failed connections" do
    user = UserIgnoringFailingConnection.new
    user.avatar = file
    expect{ user.save! }.to_not raise_error

    File.exists?(uploaded_file_server1).should be true
    File.exists?(uploaded_file_server1_medium).should be true<commit_msg>Create separate integration test cases for removal of empty directories<commit_after>require "spec_helper"
require "timeout"
require "fileutils"

describe "paperclip-storage-ftp", :integration => true do

  before(:all) do
    require "support/integration/ftp_server"
    require "support/integration/user"
    FtpServer.start
  end

  before(:each) do
    FtpServer.clear
  end

  let(:file) { File.new(File.expand_path("../support/integration/avatar.jpg", __FILE__), "rb") }
  let(:user) { User.new }

  let(:uploaded_file_server1)         { FtpServer::USER1_PATH + "/original/avatar.jpg" }
  let(:uploaded_file_server1_medium)  { FtpServer::USER1_PATH + "/medium/avatar.jpg"   }
  let(:uploaded_file_server1_thumb)   { FtpServer::USER1_PATH + "/thumb/avatar.jpg"    }
  let(:uploaded_file_server2)         { FtpServer::USER2_PATH + "/original/avatar.jpg" }
  let(:uploaded_file_server2_medium)  { FtpServer::USER2_PATH + "/medium/avatar.jpg"   }
  let(:uploaded_file_server2_thumb)   { FtpServer::USER2_PATH + "/thumb/avatar.jpg"    }

  let(:uploaded_file_server1_other)   { FtpServer::USER1_PATH + "/original/foo.txt" }

  it "stores the attachment on the ftp servers" do
    user.avatar = file
    user.save!

    File.exists?(uploaded_file_server1).should be true
    File.exists?(uploaded_file_server1_medium).should be true
    File.exists?(uploaded_file_server1_thumb).should be true
    File.exists?(uploaded_file_server2).should be true
    File.exists?(uploaded_file_server2_medium).should be true
    File.exists?(uploaded_file_server2_thumb).should be true

    file.size.should == File.size(uploaded_file_server1)
    file.size.should == File.size(uploaded_file_server2)
  end

  it "deletes an attachment from the ftp servers" do
    user.avatar = file
    user.save!

    user.destroy

    File.exists?(uploaded_file_server1).should be false
    File.exists?(uploaded_file_server1_medium).should be false
    File.exists?(uploaded_file_server1_thumb).should be false

    File.exists?(uploaded_file_server2).should be false
    File.exists?(uploaded_file_server2_medium).should be false
    File.exists?(uploaded_file_server2_thumb).should be false
  end

  it "removes empty parent directories after image deletion" do
    user.avatar = file
    user.save!

    user.destroy

    Dir.exists?(File.dirname(uploaded_file_server1)).should be false
    Dir.exists?(File.dirname(uploaded_file_server2)).should be false
  end

  it "does not remove parent directories which are not empty" do
    user.avatar = file
    user.save!

    FileUtils.touch(uploaded_file_server1_other)

    user.destroy

    File.exists?(uploaded_file_server1_other).should be true
  end

  it "survives temporarily closed ftp connections" do
    user.avatar = file
    user.save!

    user.avatar = nil
    user.save!

    FtpServer.restart

    user.avatar = file
    user.save!

    File.exists?(uploaded_file_server1).should be true
    File.exists?(uploaded_file_server2).should be true
  end

  it "allows ignoring failed connections" do
    user = UserIgnoringFailingConnection.new
    user.avatar = file
    expect{ user.save! }.to_not raise_error

    File.exists?(uploaded_file_server1).should be true
    File.exists?(uploaded_file_server1_medium).should be true
{'fraction_non_alphanumeric': 0.10191826522101752, 'fraction_numerical': 0.01134278565471226, 'mean_word_length': 4.0641891891891895, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4478474', 'n_tokens_mistral': 2014, 'n_tokens_neox': 1984, 'n_words': 371}