spec/learn_open/opener_spec.rb in learn-open-1.2.20 vs spec/learn_open/opener_spec.rb in learn-open-1.2.21

- old
+ new

@@ -1,25 +1,800 @@ require 'spec_helper' +require 'fakefs/spec_helpers' +require 'pry' describe LearnOpen::Opener do - LearnOpen::Opener::HOME_DIR = File.join(__dir__, "..", "home_dir") + include FakeFS::SpecHelpers + let(:learn_web_client) { FakeLearnClient.new(token: "some-amazing-password") } + let(:git_adapter) { FakeGit.new } + let(:system_adapter) { class_double(LearnOpen::Adapters::SystemAdapter) } - context "Verifying repo existance" do - let(:opener) { LearnOpen::Opener.new("","","") } - after do - path = File.join(__dir__, "..", "home_dir", "code") - FileUtils.rm_rf(path) + before do + create_home_dir + create_netrc_file + create_learn_config_file + end + + context "Initializer" do + it "sets the lesson" do + opener = LearnOpen::Opener.new("ttt-2-board-rb-v-000","", false) + expect(opener.target_lesson).to eq("ttt-2-board-rb-v-000") end + it "sets the editor" do + opener = LearnOpen::Opener.new("", "atom", false) + expect(opener.editor).to eq("atom") + end + it "sets the whether to open the next lesson or not" do + opener = LearnOpen::Opener.new("", "", true) + expect(opener.get_next_lesson).to eq(true) + end + end - it "returns true if .git directory for lab exists" do - expect(opener).to receive(:repo_dir).and_return("js-rubber-duck-wrangling") - FileUtils.mkdir_p("#{opener.lessons_dir}/js-rubber-duck-wrangling/.git") + context "running the opener" do + it "calls its collaborators" do + expect(system_adapter) + .to receive(:open_editor) + .with("atom", path: ".") - expect(opener.repo_exists?).to be_truthy + expect(system_adapter) + .to receive(:open_login_shell) + .with("/usr/local/bin/fish") + + expect(system_adapter) + .to receive(:change_context_directory) + .with("/home/bobby/Development/code/rails-dynamic-request-lab-cb-000") + + expect(learn_web_client) + .to receive(:fork_repo) + .with(repo_name: "rails-dynamic-request-lab-cb-000") + + opener = LearnOpen::Opener.new(nil, "atom", true, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: {"SHELL" => "/usr/local/bin/fish"}, + system_adapter: system_adapter, + io: spy) + opener.run end + end + context "Opening on specific environments" do + before do + allow(system_adapter).to receive_messages( + open_editor: :noop, + open_login_shell: :noop, + change_context_directory: :noop + ) + allow(learn_web_client).to receive(:fork_repo) + end + context "IDE" do + it "restores files and watches for changes" do + environment = { + "SHELL" => "/usr/local/bin/fish", + "LAB_NAME" => "ruby_lab", + "CREATED_USER" => "bobby", + "IDE_CONTAINER" => "true", + "IDE_VERSION" => "3" + } - it "returns false if directory for lab doesn't exists" do - expect(opener).to receive(:repo_dir).and_return("js-rubber-duck-wrangling") - expect(opener.repo_exists?).to be_falsy + create_linux_home_dir("bobby") + expect(system_adapter) + .to receive(:spawn) + .with('restore-lab', block: true) + expect(system_adapter) + .to receive(:watch_dir) + .with("/home/bobby/Development/code/ruby_lab", "backup-lab") + expect(system_adapter) + .to receive(:run_command) + .with("bundle install") + + opener = LearnOpen::Opener.new("ruby_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: environment, + system_adapter: system_adapter, + io: spy) + opener.run + end + it "does not write to the custom commands log if environment is for intended lab" do + environment = { + "SHELL" => "/usr/local/bin/fish", + "LAB_NAME" => "rails-dynamic-request-lab-cb-000", + "CREATED_USER" => "bobby", + "IDE_CONTAINER" => "true", + "IDE_VERSION" => "3" + } + allow(system_adapter).to receive_messages([:spawn, :watch_dir]) + + home_dir = create_linux_home_dir("bobby") + opener = LearnOpen::Opener.new(nil, "atom", true, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: environment, + system_adapter: system_adapter, + io: spy) + opener.run + expect(File.exist?("#{home_dir}/.custom_commands.log")).to eq(false) + end + + it "does not prompt if they want to skip lesson if the container is for a different lab" do + environment = { + "SHELL" => "/usr/local/bin/fish", + "LAB_NAME" => "Something wild", + "CREATED_USER" => "bobby", + "IDE_CONTAINER" => "true", + "IDE_VERSION" => "3" + } + io = instance_double(LearnOpen::Adapters::IOAdapter) + expect(io) + .to receive(:puts) + .with("Looking for lesson...") + + expect(io) + .to receive(:puts) + .with("Opening new window") + + create_linux_home_dir("bobby") + opener = LearnOpen::Opener.new("later_lesson", "atom", true, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: environment, + system_adapter: system_adapter, + io: io) + opener.run + end + it "prompts if they want to skip lesson" do + environment = { + "SHELL" => "/usr/local/bin/fish", + "LAB_NAME" => "later_lesson", + "CREATED_USER" => "bobby", + "IDE_CONTAINER" => "true", + "IDE_VERSION" => "3" + } + io = instance_double(LearnOpen::Adapters::IOAdapter) + expect(io) + .to receive(:puts) + .with("Looking for lesson...") + + expect(io) + .to receive(:puts) + .with("WARNING: You are attempting to open a lesson that is beyond your current lesson.") + + expect(io) + .to receive(:print) + .with("Are you sure you want to continue? [Yn]: ") + + expect(io) + .to receive(:gets) + .and_return("yes") + + expect(io) + .to receive(:puts) + .with("Opening readme...") + + create_linux_home_dir("bobby") + opener = LearnOpen::Opener.new("later_lesson", "atom", true, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: environment, + system_adapter: system_adapter, + io: io) + opener.run + end + it "writes to custom_commands_log if lab name doesn't match env" do + environment = { + "SHELL" => "/usr/local/bin/fish", + "LAB_NAME" => "Something wild", + "CREATED_USER" => "bobby", + "IDE_CONTAINER" => "true", + "IDE_VERSION" => "3" + } + allow(system_adapter).to receive_messages([:spawn, :watch_dir]) + + home_dir = create_linux_home_dir("bobby") + opener = LearnOpen::Opener.new(nil, "atom", true, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: environment, + system_adapter: system_adapter, + io: spy) + opener.run + custom_commands_log = File.read("#{home_dir}/.custom_commands.log") + expect(custom_commands_log).to eq("{\"command\":\"open_lab\",\"lab_name\":\"rails-dynamic-request-lab-cb-000\"}\n") + end + + it "writes to custom_commands_log if only if it's IDE" do + environment = { + "SHELL" => "/usr/local/bin/fish", + "LAB_NAME" => "Something wild", + "CREATED_USER" => "bobby" + } + allow(system_adapter).to receive_messages([:spawn, :watch_dir]) + + home_dir = create_linux_home_dir("bobby") + opener = LearnOpen::Opener.new(nil, "atom", true, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: environment, + system_adapter: system_adapter, + io: spy) + opener.run + expect(File.exist?("#{home_dir}/.custom_commands.log")).to eq(false) + end + + it "runs yarn install if lab is a node lab" do + environment = { + "SHELL" => "/usr/local/bin/fish", + "LAB_NAME" => "node_lab", + "CREATED_USER" => "bobby", + "IDE_CONTAINER" => "true", + } + allow(system_adapter).to receive_messages([:spawn, :watch_dir]) + expect(system_adapter) + .to receive(:open_editor) + .with("atom", path: ".") + + expect(system_adapter) + .to receive(:open_login_shell) + .with("/usr/local/bin/fish") + + expect(system_adapter) + .to receive(:change_context_directory) + .with("/home/bobby/Development/code/node_lab") + + expect(system_adapter) + .to receive(:run_command) + .with("yarn install --no-lockfile") + + opener = LearnOpen::Opener.new("node_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: environment, + system_adapter: system_adapter, + io: spy) + opener.run + end end end -end + context "Logging" do + let(:environment) {{ "SHELL" => "/usr/local/bin/fish", "JUPYTER_CONTAINER" => "true" }} + it "prints the right things" do + allow(learn_web_client).to receive(:fork_repo) + + allow(git_adapter).to receive(:clone).and_call_original + + allow(system_adapter).to receive_messages( + open_editor: :noop, + spawn: :noop, + watch_dir: :noop, + open_login_shell: :noop, + change_context_directory: :noop, + run_command: :noop, + ) + + io = StringIO.new + + opener = LearnOpen::Opener.new("jupyter_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: environment, + system_adapter: system_adapter, + io: io) + opener.run + io.rewind + expect(io.read).to eq(<<-EOF) +Looking for lesson... +Forking lesson... +Cloning lesson... +Opening lesson... +Installing pip dependencies... +Done. + EOF + end + + it "logs final status in file" do + allow(learn_web_client).to receive(:fork_repo) + + allow(git_adapter).to receive(:clone).and_call_original + + allow(system_adapter).to receive_messages( + open_editor: :noop, + spawn: :noop, + watch_dir: :noop, + open_login_shell: :noop, + change_context_directory: :noop, + run_command: :noop, + ) + + + opener = LearnOpen::Opener.new("jupyter_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: environment, + system_adapter: system_adapter, + io: spy) + opener.run + expect(File.read("#{home_dir}/.learn-open-tmp")).to eq("Done.") + end + end + context "Lab Types" do + context "Jupyter Labs" do + it "correctly opens jupyter lab on jupyter container" do + environment = { "SHELL" => "/usr/local/bin/fish", "JUPYTER_CONTAINER" => "true" } + expect(learn_web_client) + .to receive(:fork_repo) + .with(repo_name: "jupyter_lab") + + expect(git_adapter) + .to receive(:clone) + .with("git@github.com:StevenNunez/jupyter_lab.git", "jupyter_lab", {:path=>"/home/bobby/Development/code"}) + .and_call_original + + expect(system_adapter) + .to receive(:open_editor) + .with("atom", path: ".") + expect(system_adapter) + .to receive(:spawn) + .with("restore-lab", block: true) + expect(system_adapter) + .to receive(:watch_dir) + .with("/home/bobby/Development/code/jupyter_lab", "backup-lab") + expect(system_adapter) + .to receive(:open_login_shell) + .with("/usr/local/bin/fish") + expect(system_adapter) + .to receive(:change_context_directory) + .with("/home/bobby/Development/code/jupyter_lab") + expect(system_adapter) + .to receive(:run_command) + .with("/opt/conda/bin/python -m pip install -r requirements.txt") + + opener = LearnOpen::Opener.new("jupyter_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: environment, + system_adapter: system_adapter, + io: spy) + opener.run + end + + it "opens browser in IDE" do + environment = {"CREATED_USER" => "bobby", "IDE_CONTAINER" => "true", "LAB_NAME" => "jupyter_lab"} + io = StringIO.new + home_dir = create_linux_home_dir("bobby") + opener = LearnOpen::Opener.new("jupyter_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: environment, + system_adapter: system_adapter, + io: io) + opener.run + io.rewind + expect(io.read).to eq(<<-EOF) +Looking for lesson... +Opening Jupyter Lesson... +EOF + + custom_commands_log = File.read("#{home_dir}/.custom_commands.log") + expect(custom_commands_log).to eq("{\"command\":\"browser_open\",\"url\":\"https://learn.co/lessons/31322\"}\n") + end + it "opens the lab in the safari on mac" do + expect(system_adapter) + .to receive(:run_command) + .with("open -a Safari https://learn.co/lessons/31322") + io = StringIO.new + opener = LearnOpen::Opener.new("jupyter_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + system_adapter: system_adapter, + io: io, + platform: "darwin") + opener.run + io.rewind + expect(io.read).to eq(<<-EOF) +Looking for lesson... +Opening Jupyter Lesson... +EOF + end + it "opens the lab in the chrome on mac if present" do + FileUtils.mkdir_p("/Applications") + FileUtils.touch('/Applications/Google Chrome.app') + expect(system_adapter) + .to receive(:run_command) + .with("open -a 'Google Chrome' https://learn.co/lessons/31322") + + io = StringIO.new + opener = LearnOpen::Opener.new("jupyter_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + system_adapter: system_adapter, + io: io, + platform: "darwin") + opener.run + io.rewind + expect(io.read).to eq(<<-EOF) +Looking for lesson... +Opening Jupyter Lesson... +EOF + end + + it "opens the lab in the browser on linux" do + expect(system_adapter) + .to receive(:run_command) + .with("xdg-open https://learn.co/lessons/31322") + io = StringIO.new + opener = LearnOpen::Opener.new("jupyter_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + system_adapter: system_adapter, + io: io, + platform: "linux") + opener.run + io.rewind + expect(io.read).to eq(<<-EOF) +Looking for lesson... +Opening Jupyter Lesson... +EOF + end + end + context "Readme" do + it "does not open readme if on unsupported environment" do + io = StringIO.new + opener = LearnOpen::Opener.new("readme", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: {}, + system_adapter: system_adapter, + io: io, + platform: "chromeos") + opener.run + + io.rewind + expect(io.read).to eq(<<-EOF) +Looking for lesson... +It looks like this lesson is a Readme. Please open it in your browser. +EOF + end + + it "writes to custom_commands_log on IDE" do + environment = {"CREATED_USER" => "bobby", "IDE_CONTAINER" => "true", "LAB_NAME" => "readme"} + io = StringIO.new + home_dir = create_linux_home_dir("bobby") + opener = LearnOpen::Opener.new("readme", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: environment, + system_adapter: system_adapter, + io: io) + opener.run + + io.rewind + expect(io.read).to eq(<<-EOF) +Looking for lesson... +Opening readme... +EOF + custom_commands_log = File.read("#{home_dir}/.custom_commands.log") + expect(custom_commands_log).to eq("{\"command\":\"browser_open\",\"url\":\"https://learn.co/lessons/31322\"}\n") + end + context "on a mac" do + it "opens safari by default" do + io = StringIO.new + expect(system_adapter) + .to receive(:run_command) + .with("open -a Safari https://learn.co/lessons/31322") + + opener = LearnOpen::Opener.new("readme", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: {}, + system_adapter: system_adapter, + io: io, + platform: "darwin") + opener.run + + io.rewind + expect(io.read).to eq(<<-EOF) +Looking for lesson... +Opening readme... +EOF + end + + it "opens chrome if it exists" do + FileUtils.mkdir_p("/Applications") + FileUtils.touch('/Applications/Google Chrome.app') + io = StringIO.new + expect(system_adapter) + .to receive(:run_command) + .with("open -a 'Google Chrome' https://learn.co/lessons/31322") + + + opener = LearnOpen::Opener.new("readme", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: {}, + system_adapter: system_adapter, + io: io, + platform: "darwin") + opener.run + + io.rewind + expect(io.read).to eq(<<-EOF) +Looking for lesson... +Opening readme... +EOF + end + end + + context "on linux" do + it "opens in default brower" do + io = StringIO.new + expect(system_adapter) + .to receive(:run_command) + .with("xdg-open https://learn.co/lessons/31322") + + + opener = LearnOpen::Opener.new("readme", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: {}, + system_adapter: system_adapter, + io: io, + platform: "linux") + opener.run + + io.rewind + expect(io.read).to eq(<<-EOF) +Looking for lesson... +Opening readme... +EOF + end + end + end + context "iOS labs" do + it "fails to open on Linux" do + io = StringIO.new + + opener = LearnOpen::Opener.new("ios_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: {"SHELL" => "/usr/local/bin/fish"}, + system_adapter: system_adapter, + io: io, + platform: "linux") + opener.run + + io.rewind + expect(io.read).to eq(<<-EOF) +Looking for lesson... +You need to be on a Mac to work on iOS lessons. +EOF + end + + it "fails to open on the IDE" do + environment = { + "SHELL" => "/usr/local/bin/fish", + "LAB_NAME" => "ios_lab", + "CREATED_USER" => "bobby", + "IDE_CONTAINER" => "true", + "IDE_VERSION" => "3" + } + create_linux_home_dir("bobby") + io = StringIO.new + + opener = LearnOpen::Opener.new("ios_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: environment, + system_adapter: system_adapter, + io: io, + platform: "linux") + opener.run + + io.rewind + expect(io.read).to eq(<<-EOF) +Looking for lesson... +You need to be on a Mac to work on iOS lessons. +EOF + end + + it "opens xcodeproj if on a mac and it exists" do + io = StringIO.new + expect(system_adapter) + .to receive(:change_context_directory) + .with("/home/bobby/Development/code/ios_lab") + expect(system_adapter) + .to receive(:open_login_shell) + .with("/usr/local/bin/fish") + expect(system_adapter) + .to receive(:run_command) + .with("cd /home/bobby/Development/code/ios_lab && open *.xcodeproj") + + + opener = LearnOpen::Opener.new("ios_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: {"SHELL" => "/usr/local/bin/fish"}, + system_adapter: system_adapter, + io: io, + platform: "darwin") + opener.run + + end + it "opens xcworkspace if on a mac and it exists" do + io = StringIO.new + expect(system_adapter) + .to receive(:change_context_directory) + .with("/home/bobby/Development/code/ios_with_workspace_lab") + expect(system_adapter) + .to receive(:open_login_shell) + .with("/usr/local/bin/fish") + expect(system_adapter) + .to receive(:run_command) + .with("cd /home/bobby/Development/code/ios_with_workspace_lab && open *.xcworkspace") + + + opener = LearnOpen::Opener.new("ios_with_workspace_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: {"SHELL" => "/usr/local/bin/fish"}, + system_adapter: system_adapter, + io: io, + platform: "darwin") + opener.run + + end + end + context "Lab" do + context "installing dependencies" do + it "runs bundle install if lab is a ruby lab" do + allow(system_adapter) + .to receive_messages( + open_editor: ["atom", path: "."], + open_login_shell: ["/usr/local/bin/fish"], + change_context_directory: ["/home/bobby/Development/code/rails-dynamic-request-lab-cb-000"], + ) + + expect(system_adapter) + .to receive(:run_command) + .with("bundle install") + opener = LearnOpen::Opener.new("ruby_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: {"SHELL" => "/usr/local/bin/fish"}, + system_adapter: system_adapter, + io: spy) + opener.run + end + + it "outputs correctly for ruby lab" do + allow(system_adapter) + .to receive_messages( + open_editor: :noop, + open_login_shell: :noop, + change_context_directory: :noop, + run_command: :noop, + ) + + io = StringIO.new + opener = LearnOpen::Opener.new("ruby_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: {"SHELL" => "/usr/local/bin/fish"}, + system_adapter: system_adapter, + io: io) + opener.run + io.rewind + expect(io.read).to eq(<<-EOF) +Looking for lesson... +Forking lesson... +Cloning lesson... +Opening lesson... +Bundling... +Done. +EOF + end + + it "runs pip install if lab is a python lab" do + expect(system_adapter) + .to receive(:open_editor) + .with("atom", path: ".") + + expect(system_adapter) + .to receive(:open_login_shell) + .with("/usr/local/bin/fish") + + expect(system_adapter) + .to receive(:change_context_directory) + .with("/home/bobby/Development/code/python_lab") + + expect(system_adapter) + .to receive(:run_command) + .with("python -m pip install -r requirements.txt") + opener = LearnOpen::Opener.new("python_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: {"SHELL" => "/usr/local/bin/fish"}, + system_adapter: system_adapter, + io: spy) + opener.run + end + it "outputs correctly for python lab" do + allow(system_adapter) + .to receive_messages( + open_editor: :noop, + open_login_shell: :noop, + change_context_directory: :noop, + run_command: :noop, + ) + + io = StringIO.new + opener = LearnOpen::Opener.new("python_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: {"SHELL" => "/usr/local/bin/fish"}, + system_adapter: system_adapter, + io: io) + opener.run + io.rewind + expect(io.read).to eq(<<-EOF) +Looking for lesson... +Forking lesson... +Cloning lesson... +Opening lesson... +Installing pip dependencies... +Done. +EOF + end + it "runs npm install if lab is a node lab" do + expect(system_adapter) + .to receive(:open_editor) + .with("atom", path: ".") + + expect(system_adapter) + .to receive(:open_login_shell) + .with("/usr/local/bin/fish") + + expect(system_adapter) + .to receive(:change_context_directory) + .with("/home/bobby/Development/code/node_lab") + + expect(system_adapter) + .to receive(:run_command) + .with("npm install") + opener = LearnOpen::Opener.new("node_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: {"SHELL" => "/usr/local/bin/fish"}, + system_adapter: system_adapter, + io: spy) + opener.run + end + it "outputs correctly for node lab" do + allow(system_adapter) + .to receive_messages( + open_editor: :noop, + open_login_shell: :noop, + change_context_directory: :noop, + run_command: :noop, + ) + + io = StringIO.new + opener = LearnOpen::Opener.new("node_lab", "atom", false, + learn_web_client: learn_web_client, + git_adapter: git_adapter, + environment_vars: {"SHELL" => "/usr/local/bin/fish"}, + system_adapter: system_adapter, + io: io) + opener.run + io.rewind + expect(io.read).to eq(<<-EOF) +Looking for lesson... +Forking lesson... +Cloning lesson... +Opening lesson... +Installing npm dependencies... +Done. +EOF + end + end + end + end + end