diff --git a/lib/vagrant/util/mime.rb b/lib/vagrant/util/mime.rb index c528ef75c..667402747 100644 --- a/lib/vagrant/util/mime.rb +++ b/lib/vagrant/util/mime.rb @@ -6,31 +6,38 @@ module Vagrant module Mime class Multipart + # @return [Array] collection of content part of the multipart mime attr_accessor :content + # @return [String] type of the content attr_accessor :content_type + # @return [Hash] headers for the mime attr_accessor :headers - attr_accessor :mime_version - - def initialize(content_type="multipart/mixed", mime_version="1.0") - @content_id = "#{SecureRandom.alphanumeric(24)}@#{SecureRandom.alphanumeric(24)}.local" + # @param [String] (optional) mime content type + # @param [String] (optional) mime version + def initialize(content_type="multipart/mixed") + @content_id = "#{Time.now.to_i}@#{SecureRandom.alphanumeric(24)}.local" @boundary = "Boundary_#{SecureRandom.alphanumeric(24)}" @content_type = MIME::Types[content_type].first @content = [] - @mime_version = mime_version @headers = { "Content-ID"=> "<#{@content_id}>", "Content-Type"=> "#{content_type}; boundary=#{@boundary}", } end + # Add an entry to the multipart mime + # + # @param entry to add def add(entry) content << entry end # Output MimeEntity as a string + # + # @return [String] mime data def to_s output_string = "" headers.each do |k, v| @@ -47,19 +54,26 @@ module Vagrant class Entity + # @return [String] entity content attr_reader :content + # @return [String] type of the entity content attr_reader :content_type + # @param [String] entity content + # @param [String] type of the entity content def initialize(content, content_type) if !MIME::Types.include?(content_type) MIME::Types.add(MIME::Type.new(content_type)) end @content = content @content_type = MIME::Types[content_type].first - @content_id = "#{SecureRandom.alphanumeric(24)}@#{SecureRandom.alphanumeric(24)}.local" + @content_id = "#{Time.now.to_i}@#{SecureRandom.alphanumeric(24)}.local" end + # Output MimeEntity as a string + # + # @return [String] mime data def to_s output_string = "Content-ID: <#{@content_id}>\n" output_string += "Content-Type: #{@content_type}\n\n" diff --git a/test/unit/vagrant/util/mime_test.rb b/test/unit/vagrant/util/mime_test.rb new file mode 100644 index 000000000..a2dfdfb87 --- /dev/null +++ b/test/unit/vagrant/util/mime_test.rb @@ -0,0 +1,85 @@ +require File.expand_path("../../../base", __FILE__) + +require 'vagrant/util/mime' +require 'mime/types' + +describe Vagrant::Util::Mime::Multipart do + + subject { described_class } + + let(:time) { 603907018 } + let(:secure_random) { "123qwe" } + + before do + allow(Time).to receive(:now).and_return(time) + allow(SecureRandom).to receive(:alphanumeric).and_return(secure_random) + end + + it "can add headers" do + mime = subject.new() + mime.headers["Mime-Version"] = "1.0" + expected_string = "Content-ID: <#{time}@#{secure_random}.local> +Content-Type: multipart/mixed; boundary=Boundary_#{secure_random} +Mime-Version: 1.0 + +--Boundary_#{secure_random} +" + expect(mime.to_s).to eq(expected_string) + end + + it "can add content" do + mime = subject.new() + mime.add("something") + expected_string = "Content-ID: <#{time}@#{secure_random}.local> +Content-Type: multipart/mixed; boundary=Boundary_#{secure_random} + +--Boundary_#{secure_random} +something +--Boundary_#{secure_random} +" + expect(mime.to_s).to eq(expected_string) + end + + it "can add Vagrant::Util::Mime::Entity content" do + mime = subject.new() + mime.add(Vagrant::Util::Mime::Entity.new("something", "text/cloud-config")) + expected_string = "Content-ID: <#{time}@#{secure_random}.local> +Content-Type: multipart/mixed; boundary=Boundary_#{secure_random} + +--Boundary_#{secure_random} +Content-ID: <#{time}@#{secure_random}.local> +Content-Type: text/cloud-config + +something +--Boundary_#{secure_random} +" + expect(mime.to_s).to eq(expected_string) + end +end + +describe Vagrant::Util::Mime::Entity do + + subject { described_class } + + let(:time) { 603907018 } + let(:secure_random) { "123qwe" } + + before do + allow(Time).to receive(:now).and_return(time) + allow(SecureRandom).to receive(:alphanumeric).and_return(secure_random) + end + + it "registers the content type" do + subject.new("something", "text/cloud-config") + expect(MIME::Types).to include("text/cloud-config") + end + + it "outputs as a string" do + entity = subject.new("something", "text/cloud-config") + expected_string = "Content-ID: <#{time}@#{secure_random}.local> +Content-Type: text/cloud-config + +something" + expect(entity.to_s).to eq(expected_string) + end +end