require 'spec_helper' describe Noumenon::ContentRepository::FileSystem do let(:content_path) { File.join(File.dirname(__FILE__), "..", "..", "..", "..", "tmp", "content") } around do |example| FileUtils.mkdir_p content_path example.run FileUtils.rm_r content_path end subject do Noumenon::ContentRepository::FileSystem.new path: content_path end describe "initialization" do context "when no path option is provided" do it "should raise an ArgumentError" do lambda { Noumenon::ContentRepository::FileSystem.new }.should raise_error ArgumentError end it "should provide details of the error of how to resolve the error" do begin Noumenon::ContentRepository::FileSystem.new rescue ArgumentError => e e.to_s.should == "You must provide a path to the content repository: Noumenon::ContentRepository::FileSystem.new(path: '/tmp')" end end end end it { should implement(:put, "/", foo: "bar") } describe "putting content in the repository" do context "when writing to a top level file" do it "creates a YAML file at the specified path" do lambda { subject.put "example", { template: "static" } }.should create_file File.join(content_path, "example.yml") end it "writes the provided hash to the specified path" do subject.put "example", { template: "static" } YAML.load(File.read(File.join(content_path, "example.yml"))).should == { template: "static" } end it "symbolises any field keys" do subject.put "example", { "template" => "static" } YAML.load(File.read(File.join(content_path, "example.yml"))).should == { template: "static" } end end context "when writing to a sub-directory" do context "without an existing YAML file" do it "creates the tree leading to the file" do lambda { subject.put "sub_directory/example", { template: "static" } }.should create_file File.join(content_path, "sub_directory", "example.yml") end end context "when a file in the path already exists" do before(:each) { subject.put "sub_directory", { example: true } } it "creates the tree to the file" do lambda { subject.put "sub_directory/example", { template: "static" } }.should create_directory File.join(content_path, "sub_directory") end it "it moves the existing file into an index.yml file in the path" do lambda { subject.put "sub_directory/example", { template: "static" } }.should move_file({ from: File.join(content_path, "sub_directory.yml"), to: File.join(content_path, "sub_directory", "index.yml") }) end end context "when the directory specified already exists" do before(:each) { FileUtils.mkdir File.join(content_path, "sub_directory") } it "creates the file as index.yml within the directory" do lambda { subject.put "sub_directory", { template: "static" } }.should create_file File.join(content_path, "sub_directory", "index.yml") end end end end it { should implement(:get, "/") } describe "retrieving content from the repository" do context "when the item does not exist" do it "returns nil" do subject.get("not_found").should be_nil end end context "when the item exists" do it "returns it's content in hash form" do subject.put "example", { template: "static" } subject.get("example").should == { template: "static" } end it "supports items with string based keys" do File.open(File.join(content_path, "example.yml"), "w") { |f| f.print("template: foo") } subject.get("example").should == { template: "foo" } end end context "when the item is a directory" do it "returns the contents of index.yml if it exists" do subject.put "example/index", { template: "static" } subject.get("example").should == { template: "static" } end it "returns nil if no index.yml exists" do subject.put "example/page", { template: "static" } subject.get("example").should be_nil end end end it { should implement(:children) } describe "listing child items" do before do subject.put("/", title: "Home") subject.put("/about", title: "About") subject.put("/about/team", title: "Team") subject.put("/about/location", title: "Location") subject.put("/contact", title: "Contact") end context "a single level from the root" do it "returns an array" do subject.children.should be_instance_of Array end it "does not list items below the top level" do subject.children("/").should have(2).items end describe "each item" do let(:items) { subject.children("/") } it "is a hash" do items[0].should be_instance_of Hash end it "has a path" do items[0][:path].should == "/about" items[1][:path].should == "/contact" end it "has a title" do items[0][:title].should == "About" items[1][:title].should == "Contact" end end end context "multiple levels from the root" do let(:items) { subject.children("/", 2) } describe "an item with children" do it "has an array of children" do items[0][:children].should have(2).items end end end context "from a point below the root" do let(:items) { subject.children("/about") } it "lists only items below that point" do items.should have(2).items items[0][:title].should == "Location" items[1][:title].should == "Team" end end end end