         expect(lastAjaxCall().args[0].url).toEqual(url + "/user")
       )
     )
-  )
-  
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-  # Assocsiations
-  # ----------------------------------------------------------------
-
-  describe("Associations", ->
-
-    project = null
+
+    describe("Associations", ->
+      it("returns empty GitLab.Keys collection on user.sshkeys", ->
+        keys = gitlab.user.sshkeys
+        expect(keys.backboneClass).toEqual("SSHKeys")
+        expect(keys.length).toBe(0)
+      )
+    )
+  )
+
+  # GitLab.Project
+  # ----------------------------------------------------------------
+
+  describe("Project", ->
+
+    describe("fetch()", ->
+      it("should call the correct URL", ->
+        spyOnAjax()
+        project = gitlab.project("runemadsen/book") # load any.get.json instead of subfolder index.get.json
+        project.fetch()
+        expect(lastAjaxCall().args[0].type).toEqual("GET")
+        expect(lastAjaxCall().args[0].url).toEqual(url + "/projects/runemadsen%2Fbook") 
+      )
+    )
+
+    # should set "book" and "runemadsen" individually
+    # CHECK THAT PATH GETS SET INSIDE PROJECT MODEL, NOT FROM GITLAB.project() 
+    #expect(project.get("path")).toEqual("book")
+    #expect(project.get("path_with_namespace")).toEqual("runemadsen/book")
+    #expect(project.id).toBe(undefined)
+
+    describe("Associations", ->
+      
+      it("returns empty GitLab.Branches collection on project.branches", ->
+        branches = project.branches
+        expect(branches.backboneClass).toEqual("Branches")
+        expect(branches.project).toEqual(project)
+        expect(branches.length).toBe(0)
+      )
+
+      it("returns empty GitLab.Members collection on project.members", ->
+        expect(project.members.backboneClass).toEqual("Members")
+      )
+  
+      it("returns empty GitLab.Blob model on project.blob(path)", ->
+        blob = project.blob("subfolder/file.txt")
+        expect(blob.backboneClass).toEqual("Blob")
+        expect(blob.project).toEqual(project)
+        expect(blob.get("name")).toEqual("subfolder/file.txt")
+      )
+  
+      it("returns empty GitLab.Blob model on project.blob(path, branch)", ->
+        blob = project.blob("subfolder/file.txt", "slave")
+        expect(blob.backboneClass).toEqual("Blob")
+        expect(blob.project).toEqual(project)
+        expect(blob.branch).toEqual("slave")
+        expect(blob.get("name")).toEqual("subfolder/file.txt")
+      )
+  
+      it("returns empty GitLab.Tree model on project.tree(path)", ->
+        tree = project.tree("/")
+        expect(tree.backboneClass).toEqual("Tree")
+        expect(tree.project).toEqual(project)
+      )
+  
+      it("returns empty GitLab.Tree model on project.tree(path, branch)", ->
+        tree = project.tree("/", "slave")
+        expect(tree.backboneClass).toEqual("Tree")
+        expect(tree.project).toEqual(project)
+        expect(tree.branch).toEqual("slave")
+      )
+    )
+  )
+
+  # GitLab.Branches
+  # ----------------------------------------------------------------
+
+  describe("Branches", ->
+
+    branches = null
+    beforeEach(-> branches = new GitLab.Branches([], project:project))
+
+    describe("initialize()", ->
+      it("should complain no project is passed in options", ->
+        expect(true).toBe(false)
+      )
+    )
+
+    describe("fetch()", ->
+      it("should call the correct URL", ->
+        spyOnAjax()
+        branches.fetch()
+        expect(lastAjaxCall().args[0].type).toEqual("GET")
+        expect(lastAjaxCall().args[0].url).toEqual(url + "/projects/owner%2Fproject/repository/branches") 
+      )
+    )
+  )
+
+  # GitLab.Members
+  # ----------------------------------------------------------------
+
+  describe("Members", ->
+
+    members = null
+    beforeEach(-> members = new GitLab.Members([], project:project))
+
+    describe("initialize()", ->
+      it("should complain no project is passed in options", ->
+        expect(true).toBe(false)
+      )
+    )
+
+    describe("fetch()", ->
+      it("should call the correct URL", ->
+        spyOnAjax()
+        members.fetch()
+        expect(lastAjaxCall().args[0].type).toEqual("GET")
+        expect(lastAjaxCall().args[0].url).toEqual(url + "/projects/owner%2Fproject/members") 
+      )
+    )
+
+    describe("create()", ->
+      it("should call the correct URL", ->
+        spyOnAjax()
+        members.create(name:"Rune Madsen")
+        expect(lastAjaxCall().args[0].type).toEqual("POST")
+        expect(lastAjaxCall().args[0].url).toEqual(url + "/projects/owner%2Fproject/members")
+      )
+    )
+  )
+
+  # GitLab.Tree
+  # ----------------------------------------------------------------
+
+  describe("Tree", ->
+
+    describe("initialize()", ->
+      it("should complain if no project, path are passed in options", ->
+        expect(true).toBe(false)
+      )
+    )
+
+    describe("fetch()", ->
+
+      it("should call correct URL", ->
+        spyOnAjax()
+        tree = new GitLab.Tree([]
+        , 
+          project:project
+          path:"/"
+        )
+        tree.fetch()
+        expect(lastAjaxCall().args[0].type).toEqual("GET")
+        expect(lastAjaxCall().args[0].url).toEqual(url + "/projects/owner%2Fproject/repository/tree")
+        expect(last_call_data.path).toEqual("%2F")
+      )
+
+      it("should call correct URL with branch", ->
+        spyOnAjax()
+        tree = new GitLab.Tree([]
+        , 
+          project:project
+          path:"/"
+          branch:"slave"
+        )
+        tree.fetch()
+        expect(last_call_data.ref_name).toEqual("slave")
+      )
+
+      it("should parse trees and blobs", ->
+        tree = new GitLab.Tree([], project:project, path:"/")
+        tree.fetch()
+        waitsFor(->
+          return tree.length > 0
+        , "tree never loaded", ajaxTimeout
+        )
+        runs(->
+          # put blobs in models array
+          expect(tree.length).toBe(1)
+          blob = tree.first()
+          expect(blob.backboneClass).toEqual("Blob")
+          
+          # put trees in trees array
+          expect(tree.trees.length).toBe(1)
+          subfolder = tree.trees[0]
+          expect(subfolder.backboneClass).toEqual("Tree")
+          expect(subfolder.path).toEqual("assets")
+          expect(subfolder.length).toBe(0)
+        )
+      )
+    )
+  )
+
+  # GitLab.Blob
+  # ----------------------------------------------------------------
+
+  describe("Blob", ->
+    
+    masterBlob = null
+    slaveBlob = null
 
     beforeEach(->
-      project = gitlab.project("runemadsen/book")
-    )
-
-    
-
-    it("returns empty GitLab.Keys collection on user.sshkeys", ->
-      keys = gitlab.user.sshkeys
-      expect(keys.backboneClass).toEqual("SSHKeys")
-      expect(keys.length).toBe(0)
-    )
-
-    it("returns empty GitLab.Project model on gitlab.project()", ->
-      expect(project.backboneClass).toEqual("Project")
-    )
-
-    it("returns empty GitLab.Branches collection on project.branches", ->
-      branches = project.branches
-      expect(branches.backboneClass).toEqual("Branches")
-      expect(branches.project).toEqual(project)
-      expect(branches.length).toBe(0)
-    )
-
-    it("returns empty GitLab.Blob model on project.blob(path)", ->
-      blob = project.blob("subfolder/file.txt")
-      expect(blob.backboneClass).toEqual("Blob")
-      expect(blob.project).toEqual(project)
-      expect(blob.get("name")).toEqual("subfolder/file.txt")
-    )
-
-    it("returns empty GitLab.Blob model on project.blob(path, branch)", ->
-      blob = project.blob("subfolder/file.txt", "slave")
-      expect(blob.backboneClass).toEqual("Blob")
-      expect(blob.project).toEqual(project)
-      expect(blob.branch).toEqual("slave")
-      expect(blob.get("name")).toEqual("subfolder/file.txt")
-    )
-
-    it("returns empty GitLab.Tree model on project.tree(path)", ->
-      tree = project.tree("/")
-      expect(tree.backboneClass).toEqual("Tree")
-      expect(tree.project).toEqual(project)
-    )
-
-    it("returns empty GitLab.Tree model on project.tree(path, branch)", ->
-      tree = project.tree("/", "slave")
-      expect(tree.backboneClass).toEqual("Tree")
-      expect(tree.project).toEqual(project)
-      expect(tree.branch).toEqual("slave")
-    )
-  )
+      masterBlob = new GitLab.Blob(
+        name: "subfolder/master.txt"
+      ,
+        project: project1
+      )
+
+      slaveBlob = new GitLab.Blob(
+        name: "subfolder/slave.txt"
+      ,
+        project: project1
+        branch: "slave"
+      )
+    )
+
+    it("should fail if correct options are not given", ->
+      expect(true).toBe(false)
+    )
+
+    describe("fetchContent()", ->
+
+      it("should fetch the blob contents and merge with other data", ->
+        spyOnAjax()
+        masterBlob.fetchContent()
+        waitsFor(->
+          return masterBlob.get("content")
+        , "blob content never loaded", ajaxTimeout
+        )
+        runs(->
+          expect(lastAjaxCall().args[0].url).toEqual(url + "/projects/owner%2Fproject/repository/blobs/master?filepath=subfolder/master.txt")
+          expect(masterBlob.get("content")).toEqual("Hello!")
+          expect(masterBlob.get("name")).toEqual("subfolder/master.txt")
+        )
+      )
+  
+      it("should use branch if specified", ->
+        spyOnAjax()
+        slaveBlob.fetchContent()
+        expect(lastAjaxCall().args[0].url).toEqual(url + "/projects/owner%2Fproject/repository/blobs/slave?filepath=subfolder/slave.txt")
+      )
+    )
+
+    describe("defaultCommitMessage()", ->
+
+      it("should give correct message when isNew", ->
+        expect(masterBlob.defaultCommitMessage()).toEqual("Created subfolder/master.txt")
+      )
+
+      it("should give correct message when !isNew", ->
+        masterBlob.set("id", 1)
+        expect(masterBlob.defaultCommitMessage()).toEqual("Updated subfolder/master.txt")
+      )
+    )
+
+    describe("save()", ->
+
+      describe("CREATE", ->
+
+        it("should use correct defaults", ->
+          spyOnAjax() 
+          masterBlob.set("content", "New Content")
+          masterBlob.save()
+          expect(lastAjaxCall().args[0].url).toEqual(url + "/projects/owner%2Fproject/repository/files")
+          expect(lastAjaxCall().args[0].type).toEqual("POST")
+          expect(JSON.parse(lastAjaxCall().args[0].data)).toEqual(
+            file_name: "master.txt"
+            file_path: "subfolder/"
+            content: "New Content"
+            commit_message: "Created subfolder/master.txt"
+            branch_name: "master"
+          )
+        )
+  
+        it("should use branch and commit message if specified", ->
+          spyOnAjax() 
+          slaveBlob.set("content", "New Content")
+          slaveBlob.save(
+            commit_message: "Another Message"
+          )
+          expect(lastAjaxCall().args[0].url).toEqual(url + "/projects/owner%2Fproject/repository/files")
+          expect(lastAjaxCall().args[0].type).toEqual("POST")
+          expect(JSON.parse(lastAjaxCall().args[0].data)).toEqual(
+            file_name: "slave.txt"
+            file_path: "subfolder/"
+            content: "New Content"
+            commit_message: "Another Message"
+            branch_name: "slave"
+          )
+        )
+      )
+  
+      describe("UPDATE", ->
+        # CHECK THAT MODEL fetchContent or tree() always gives back a blob model that calls update, not create!!!!
+      )
+    )
+  )
+
+  # MAKE SURE THAT ALL ASSOCIATIONS HAVE MINIMUM OF DATA TO DO STUFF
 
   # CHECK THAT ALL MODELS THAT REWUIRE BRANCHES FAIL WHEN NOT PASSED IN
 
   # KEYS!!!!
-
-  # CHCK PROJECT URL!!!!!
-  # expect(project.url()).toEqual(url + "/projects/runemadsen%2Fbook")
-  
-  # CHECK THAT PATH GETS SET INSIDE PROJECT MODEL, NOT FROM GITLAB.project() 
-  #expect(project.get("path")).toEqual("book")
-  #expect(project.get("path_with_namespace")).toEqual("runemadsen/book")
-  #expect(project.id).toBe(undefined)
 
   # CHECK TREE URL
   # expect(tree.url()).toEqual(url + "/projects/owner%2Fproject/repository/tree?path=%2F&ref_name=master")

      it("returns empty GitLab.User model on gitlab.user", ->
        expect(gitlab.user.backboneClass).toEqual("User")
      )
    )
  )

  # GitLab.User
  # ----------------------------------------------------------------

  describe("GitLab.User", ->

    describe("fetch()", ->
      it("should call correct URL", ->

  #        expect(user.sshkeys.first().get("title")).toEqual("Public key")
  #      )
  #    )
)

# make sure that the trees api returns full path in blob names when listing a subfolder. Otherwise blob.get("name") logic is wrong.
