require 'spec_helper' describe IcecastMount do let(:icecast_mount) { FactoryGirl.create(:icecast_mount) } let(:output) { StringIO.new } let(:builder) { ::Builder::XmlMarkup.new(:target => output, :indent => 1) } it "save error" do mount = IcecastMount.new mount.save.should be_false mount.errors[:name].should == ["can't be blank", "must start with /"] end it "save" do mount = IcecastMount.new mount.name = "/" + Faker::Lorem.characters(10) mount.stream_name = Faker::Lorem.characters(10) mount.stream_description = Faker::Lorem.characters(10) mount.stream_url = Faker::Lorem.characters(10) mount.genre = Faker::Lorem.characters(10) mount.source_username = Faker::Lorem.characters(10) mount.source_pass = Faker::Lorem.characters(10) mount.intro = Faker::Lorem.characters(10) mount.fallback_mount = Faker::Lorem.characters(10) mount.on_connect = Faker::Lorem.characters(10) mount.on_disconnect = Faker::Lorem.characters(10) mount.fallback_override = true mount.fallback_when_full = true mount.max_listeners = 1000 mount.max_listener_duration = 3600 mount.authentication = FactoryGirl.create(:icecast_user_authentication) mount.server = FactoryGirl.create(:icecast_server_with_overrides) mount.save! mount.dumpXml(builder) output.rewind xml = Nokogiri::XML(output) xml.css('mount mount-name').text.should == mount.name xml.css('mount username').text.should == mount.source_username xml.css('mount password').text.should == mount.source_pass xml.css('mount max-listeners').text.should == mount.max_listeners.to_s xml.css('mount max-listener-duration').text.should == mount.max_listener_duration.to_s xml.css('mount intro').text.should == mount.intro xml.css('mount fallback-mount').text.should == mount.fallback_mount xml.css('mount fallback-override').text.should == mount.fallback_override.to_s xml.css('mount fallback-when-full').text.should == mount.fallback_when_full.to_s xml.css('mount stream-name').text.should == mount.stream_name xml.css('mount stream-description').text.should == mount.stream_description xml.css('mount stream-url').text.should == mount.stream_url xml.css('mount genre').text.should == mount.genre xml.css('mount bitrate').length.should == 0 xml.css('mount charset').text == mount.charset xml.css('mount public').text == mount.is_public.to_s xml.css('mount type').text == mount.mime_type xml.css('mount subtype').text == mount.subtype xml.css('mount burst-size').length.should == 0 xml.css('mount mp3-metadata-interval').length.should == 0 xml.css('mount hidden').text.should == mount.hidden.to_s xml.css('mount on-connect').text.should == mount.on_connect xml.css('mount on-disconnect').text.should == mount.on_disconnect xml.css('mount dump-file').length.should == 0 xml.css('mount authentication').length.should == 1 # no reason to test futher; it's tested in that model end describe "override xml over mount template" do let(:mount) {FactoryGirl.create(:iceast_mount_with_template)} it "should allow override by mount" do mount.dumpXml(builder) output.rewind xml = Nokogiri::XML(output) xml.css('mount mount-name').text.should == mount.name xml.css('mount username').text.should == mount.source_username xml.css('mount bitrate').text.should == mount.bitrate.to_s xml.css('mount type').text.should == mount.mount_template.mime_type xml.css('mount stream-url').text.should == mount.stream_url # now see the stream_url, and bitrate, go back to the template's value because we set it to nil mount.bitrate = nil mount.stream_url = nil mount.save! output = StringIO.new builder = ::Builder::XmlMarkup.new(:target => output, :indent => 1) mount.dumpXml(builder) output.rewind xml = Nokogiri::XML(output) xml.css('mount bitrate').text.should == mount.mount_template.bitrate.to_s xml.css('mount stream-url').text.should == mount.mount_template.stream_url end end describe "poke configs" do let(:server) { a = FactoryGirl.create(:icecast_server_with_overrides); a.config_updated; IcecastServer.find(a.id) } before(:each) do server.mounts << FactoryGirl.create(:icecast_mount, server: server) server.save! server.config_updated server.reload server.config_changed.should == 0 end it "success via server" do server.mounts.first.save! server.reload server.config_changed.should == 1 end it "success when deleted" do server.mounts.first.destroy server.reload server.config_changed.should == 1 end end describe "icecast server callbacks" do it "source up" do icecast_mount.source_up end end describe "listener/source" do let(:mount) {FactoryGirl.create(:iceast_mount_with_template)} describe "listeners" do it "listener_add" do mount.listener_add mount.listeners.should == 1 end it "listener_remove when at 0" do mount.listener_remove mount.listeners.should == 0 end it "listener_remove" do mount.listener_add mount.listener_remove mount.listeners.should == 0 end end describe "sources" do it "source_up" do mount.source_up mount.sourced.should == true end end describe "sources" do it "source_down" do mount.source_up mount.source_down mount.sourced.should == false end end end describe "build_session_mount" do let(:server1) {FactoryGirl.create(:icecast_server_minimal)} let(:server2) {FactoryGirl.create(:icecast_server_with_overrides)} let(:server3) {FactoryGirl.create(:icecast_server_with_overrides)} let(:hidden_music_session) { FactoryGirl.create(:music_session, :fan_access => false)} let(:public_music_session) { FactoryGirl.create(:music_session, :fan_access => true)} let(:public_music_session2) { FactoryGirl.create(:music_session, :fan_access => true)} let(:public_music_session3) { FactoryGirl.create(:music_session, :fan_access => true)} before(:each) do end it "no fan access means no mount" do mount = IcecastMount.build_session_mount(hidden_music_session) mount.should be_nil end it "with no servers" do IcecastServer.count.should == 0 mount = IcecastMount.build_session_mount(public_music_session) mount.should be_nil end it "with a server that has a mount template" do server1.mount_template.should_not be_nil mount = IcecastMount.build_session_mount(public_music_session) mount.should_not be_nil mount.save! end it "with a server that already has an associated mount" do server1.mount_template.should_not be_nil mount = IcecastMount.build_session_mount(public_music_session) mount.save! mount = IcecastMount.build_session_mount(public_music_session2) mount.save! server1.reload server1.mounts.length.should == 2 end it "picks a second server once the 1st has been chosen" do server1.touch mount = IcecastMount.build_session_mount(public_music_session) mount.listeners = 1 # affect the weight mount.save! server2.touch mount = IcecastMount.build_session_mount(public_music_session2) mount.save! server1.reload server1.mounts.length.should == 1 server2.reload server2.mounts.length.should == 1 end it "picks the 1st server again once the 2nd has higher weight" do server1.touch mount = IcecastMount.build_session_mount(public_music_session) mount.listeners = 1 # affect the weight mount.save! server2.touch mount = IcecastMount.build_session_mount(public_music_session2) mount.sourced = 1 mount.save! mount = IcecastMount.build_session_mount(public_music_session3) mount.listeners = 1 mount.save! server1.reload server1.mounts.length.should == 2 server2.reload server2.mounts.length.should == 1 end end end