summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG4
-rw-r--r--VERSION2
-rw-r--r--app/assets/stylesheets/header.scss3
-rw-r--r--app/assets/stylesheets/themes/ui_mars.scss3
-rw-r--r--app/controllers/dashboard_controller.rb3
-rw-r--r--app/views/admin/hooks/_data_ex.html.erb93
-rw-r--r--app/views/admin/users/_form.html.haml6
-rw-r--r--app/views/dashboard/index.html.haml7
-rw-r--r--app/views/dashboard/index.js.haml2
-rw-r--r--app/views/help/api.html.haml20
-rw-r--r--app/views/help/index.html.haml3
-rw-r--r--app/views/layouts/profile.html.haml9
-rw-r--r--doc/api/README.md1
-rw-r--r--doc/api/issues.md181
-rw-r--r--lib/api.rb1
-rw-r--r--lib/api/entities.rb18
-rw-r--r--lib/api/helpers.rb4
-rw-r--r--lib/api/issues.rb111
-rw-r--r--lib/api/projects.rb24
-rw-r--r--lib/gitlab/logger.rb1
-rw-r--r--spec/api/issues_spec.rb71
21 files changed, 490 insertions, 77 deletions
diff --git a/CHANGELOG b/CHANGELOG
index fe243d65e4b..ec5d2f220d3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,6 +4,10 @@ v 2.7.0
- Git HTTP
- API
- UI improved
+ - System hooks
+ - UI improved
+ - Dashboard events endless scroll
+ - Source perfomance increased
v 2.6.0
- UI polished
diff --git a/VERSION b/VERSION
index 1daf7c48e6d..24ba9a38de6 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.7.0pre
+2.7.0
diff --git a/app/assets/stylesheets/header.scss b/app/assets/stylesheets/header.scss
index c3a570036bb..07eba39b275 100644
--- a/app/assets/stylesheets/header.scss
+++ b/app/assets/stylesheets/header.scss
@@ -125,9 +125,6 @@ header {
display: block;
cursor: pointer;
img {
- -moz-box-shadow: 0 0 5px #ccc;
- -webkit-box-shadow: 0 0 5px #ccc;
- box-shadow: 0 0 5px #ccc;
border-radius: 4px;
right: 5px;
position: absolute;
diff --git a/app/assets/stylesheets/themes/ui_mars.scss b/app/assets/stylesheets/themes/ui_mars.scss
index 0fea6144431..39dcab1d085 100644
--- a/app/assets/stylesheets/themes/ui_mars.scss
+++ b/app/assets/stylesheets/themes/ui_mars.scss
@@ -70,8 +70,7 @@
}
}
.separator {
- border-color:#444;
- background:#31363E;
+ display:none;
}
}
diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb
index 14f6ab1c31a..8508e2454d2 100644
--- a/app/controllers/dashboard_controller.rb
+++ b/app/controllers/dashboard_controller.rb
@@ -3,11 +3,12 @@ class DashboardController < ApplicationController
def index
@projects = current_user.projects_with_events.page(params[:page]).per(40)
- @events = Event.recent_for_user(current_user).limit(20)
+ @events = Event.recent_for_user(current_user).limit(20).offset(params[:offset] || 0)
@last_push = current_user.recent_push
respond_to do |format|
format.html
+ format.js
format.atom { render :layout => false }
end
end
diff --git a/app/views/admin/hooks/_data_ex.html.erb b/app/views/admin/hooks/_data_ex.html.erb
index 8d3de3f0bf2..652ee5aa56f 100644
--- a/app/views/admin/hooks/_data_ex.html.erb
+++ b/app/views/admin/hooks/_data_ex.html.erb
@@ -1,44 +1,65 @@
<% data_ex_str = <<eos
+1. Project created:
{
- :before => "95790bf891e76fee5e1747ab589903a6a1f80f22",
- :after => "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
- :ref => "refs/heads/master",
- :user_id => 4,
- :user_name => "John Smith",
- :repository => {
- :name => "Diaspora",
- :url => "localhost/diaspora",
- :description => "",
- :homepage => "localhost/diaspora",
- :private => true
- },
- :commits => [
- [0] {
- :id => "450d0de7532f8b663b9c5cce183b...",
- :message => "Update Catalan translation to e38cb41.",
- :timestamp => "2011-12-12T14:27:31+02:00",
- :url => "http://localhost/diaspora/commits/450d0de7532f...",
- :author => {
- :name => "Jordi Mallach",
- :email => "jordi@softcatala.org"
- }
- },
+ "created_at": "2012-07-21T07:30:54Z",
+ "event_name": "project_create",
+ "name": "StoreCloud",
+ "owner_email": "johnsmith@gmail.com",
+ "owner_name": "John Smith",
+ "path": "storecloud",
+ "project_id": 74
+}
+
+2. Project destroyed:
+{
+ "event_name": "project_destroy",
+ "name": "Underscore",
+ "owner_email": "johnsmith@gmail.com",
+ "owner_name": "John Smith",
+ "path": "underscore",
+ "project_id": 73
+}
+
+3. New Team Member:
+{
+ "created_at": "2012-07-21T07:30:56Z",
+ "event_name": "user_add_to_team",
+ "project_access": "Master",
+ "project_id": 74,
+ "project_name": "StoreCloud",
+ "project_path": "storecloud",
+ "owner_email": "johnsmith@gmail.com",
+ "owner_name": "John Smith",
+}
+
+4. Team Member Removed:
+{
+ "created_at": "2012-07-21T07:30:56Z",
+ "event_name": "user_remove_from_team",
+ "project_access": "Master",
+ "project_id": 74,
+ "project_name": "StoreCloud",
+ "project_path": "storecloud",
+ "owner_email": "johnsmith@gmail.com",
+ "owner_name": "John Smith",
+}
- ....
+5. User created:
+{
+ "created_at": "2012-07-21T07:44:07Z",
+ "email": "js@gitlabhq.com",
+ "event_name": "user_create",
+ "name": "John Smith"
+}
- [3] {
- :id => "da1560886d4f094c3e6c9ef40349...",
- :message => "fixed readme",
- :timestamp => "2012-01-03T23:36:29+02:00",
- :url => "http://localhost/diaspora/commits/da1560886d...",
- :author => {
- :name => "gitlab dev user",
- :email => "gitlabdev@dv6700.(none)"
- }
- }
- ],
- total_commits_count => 3
+6. User removed:
+{
+ "created_at": "2012-07-21T07:44:07Z",
+ "email": "js@gitlabhq.com",
+ "event_name": "user_destroy",
+ "name": "John Smith"
}
+
eos
%>
<% js_lexer = Pygments::Lexer[:js] %>
diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml
index bd2e136247a..c1955b321d5 100644
--- a/app/views/admin/users/_form.html.haml
+++ b/app/views/admin/users/_form.html.haml
@@ -50,7 +50,7 @@
.alert
.clearfix
- %p Give user ability to manage application.
+ %p Make the user a GitLab administrator.
= f.label :admin, :class => "checkbox" do
= f.check_box :admin
%span Administrator
@@ -59,11 +59,11 @@
- if @admin_user.blocked
%span
= link_to 'Unblock', unblock_admin_user_path(@admin_user), :method => :put, :class => "btn small"
- This user is blocked and is not able to login GitLab
+ This user is blocked and is not able to login to GitLab
- else
%span
= link_to 'Block', block_admin_user_path(@admin_user), :confirm => 'USER WILL BE BLOCKED! Are you sure?', :method => :put, :class => "btn small danger"
- Blocked user will removed from all projects &amp; will not be able to login to GitLab.
+ Blocked users will be removed from all projects &amp; will not be able to login to GitLab.
.actions
= f.submit 'Save', :class => "btn primary"
- if @admin_user.new_record?
diff --git a/app/views/dashboard/index.html.haml b/app/views/dashboard/index.html.haml
index b38544509b2..e1d7781927a 100644
--- a/app/views/dashboard/index.html.haml
+++ b/app/views/dashboard/index.html.haml
@@ -10,9 +10,10 @@
add new key
to your profile
- if @events.any?
- = render @events
+ .content_list= render @events
- else
%h4.nothing_here_message Projects activity will be displayed here
+ .loading.hide
.side
= render "events/event_last_push", :event => @last_push
.projects_box
@@ -54,3 +55,7 @@
New Project ยป
- else
If you will be added to project - it will be displayed here
+
+
+:javascript
+ $(function(){ Pager.init(20); });
diff --git a/app/views/dashboard/index.js.haml b/app/views/dashboard/index.js.haml
index aa038e75928..7e5a148e5ef 100644
--- a/app/views/dashboard/index.js.haml
+++ b/app/views/dashboard/index.js.haml
@@ -1,2 +1,2 @@
:plain
- $(".projects .activities").append("#{escape_javascript(render(@events))}");
+ Pager.append(#{@events.count}, "#{escape_javascript(render(@events))}");
diff --git a/app/views/help/api.html.haml b/app/views/help/api.html.haml
index 4964c1bbd87..e184df549de 100644
--- a/app/views/help/api.html.haml
+++ b/app/views/help/api.html.haml
@@ -1,16 +1,18 @@
%h3 API
.back_link
- = link_to help_path do
+ = link_to help_path do
&larr; to index
%hr
%ol
- %li
+ %li
%a{:href => "#README"} README
- %li
+ %li
%a{:href => "#projects"} Projects
- %li
+ %li
%a{:href => "#users"} Users
+ %li
+ %a{:href => "#issues"} Issues
.file_holder#README
.file_title
@@ -39,3 +41,13 @@
.file_content.wiki
= preserve do
= markdown File.read(Rails.root.join("doc", "api", "users.md"))
+
+%br
+
+.file_holder#issues
+ .file_title
+ %i.icon-file
+ Issues
+ .file_content.wiki
+ = preserve do
+ = markdown File.read(Rails.root.join("doc", "api", "issues.md"))
diff --git a/app/views/help/index.html.haml b/app/views/help/index.html.haml
index b6c52712c4d..e9602e33037 100644
--- a/app/views/help/index.html.haml
+++ b/app/views/help/index.html.haml
@@ -24,4 +24,7 @@
%h5= link_to "Web Hooks", help_web_hooks_path
%li
+ %h5= link_to "System Hooks", help_system_hooks_path
+
+ %li
%h5= link_to "API", help_api_path
diff --git a/app/views/layouts/profile.html.haml b/app/views/layouts/profile.html.haml
index dfe48d68240..957a68bf482 100644
--- a/app/views/layouts/profile.html.haml
+++ b/app/views/layouts/profile.html.haml
@@ -12,16 +12,17 @@
%li{:class => tab_class(:password)}
= link_to "Password", profile_password_path
+ %li{:class => tab_class(:ssh_keys)}
+ = link_to keys_path do
+ SSH Keys
+ %span.count= current_user.keys.count
+
%li{:class => tab_class(:token)}
= link_to "Token", profile_token_path
%li{:class => tab_class(:design)}
= link_to "Design", profile_design_path
- %li{:class => tab_class(:ssh_keys)}
- = link_to keys_path do
- SSH Keys
- %span.count= current_user.keys.count
.content
= yield
diff --git a/doc/api/README.md b/doc/api/README.md
index dcf75afda1f..e01119661f0 100644
--- a/doc/api/README.md
+++ b/doc/api/README.md
@@ -27,3 +27,4 @@ The API uses JSON to serialize data. You don't need to specify `.json` at the en
+ [Users](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/users.md)
+ [Projects](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/projects.md)
++ [Issues](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/issues.md)
diff --git a/doc/api/issues.md b/doc/api/issues.md
new file mode 100644
index 00000000000..bad2d474020
--- /dev/null
+++ b/doc/api/issues.md
@@ -0,0 +1,181 @@
+## List issues
+
+Get all issues created by authenticed user.
+
+```
+GET /issues
+```
+
+```json
+[
+ {
+ "id": 43,
+ "title": "4xx/5xx pages",
+ "description": "",
+ "labels": [ ],
+ "milestone": null,
+ "assignee": null,
+ "author": {
+ "id": 1,
+ "email": "john@example.com",
+ "name": "John Smith",
+ "blocked": false,
+ "created_at": "2012-05-23T08:00:58Z"
+ },
+ "closed": true,
+ "updated_at": "2012-07-02T17:53:12Z",
+ "created_at": "2012-07-02T17:53:12Z"
+ },
+ {
+ "id": 42,
+ "title": "Add user settings",
+ "description": "",
+ "labels": [
+ "feature"
+ ],
+ "milestone": {
+ "id": 1,
+ "title": "v1.0",
+ "description": "",
+ "due_date": "2012-07-20",
+ "closed": false,
+ "updated_at": "2012-07-04T13:42:48Z",
+ "created_at": "2012-07-04T13:42:48Z"
+ },
+ "assignee": {
+ "id": 2,
+ "email": "jack@example.com",
+ "name": "Jack Smith",
+ "blocked": false,
+ "created_at": "2012-05-23T08:01:01Z"
+ },
+ "author": {
+ "id": 1,
+ "email": "john@example.com",
+ "name": "John Smith",
+ "blocked": false,
+ "created_at": "2012-05-23T08:00:58Z"
+ },
+ "closed": false,
+ "updated_at": "2012-07-12T13:43:19Z",
+ "created_at": "2012-06-28T12:58:06Z"
+ }
+]
+```
+
+## List project issues
+
+Get a list of project issues.
+
+```
+GET /projects/:id/issues
+```
+
+Parameters:
+
++ `id` (required) - The code name of a project
+
+## Single issue
+
+Get a project issue.
+
+```
+GET /projects/:id/issues/:issue_id
+```
+
+Parameters:
+
++ `id` (required) - The code name of a project
++ `issue_id` (required) - The ID of a project issue
+
+```json
+{
+ "id": 42,
+ "title": "Add user settings",
+ "description": "",
+ "labels": [
+ "feature"
+ ],
+ "milestone": {
+ "id": 1,
+ "title": "v1.0",
+ "description": "",
+ "due_date": "2012-07-20",
+ "closed": false,
+ "updated_at": "2012-07-04T13:42:48Z",
+ "created_at": "2012-07-04T13:42:48Z"
+ },
+ "assignee": {
+ "id": 2,
+ "email": "jack@example.com",
+ "name": "Jack Smith",
+ "blocked": false,
+ "created_at": "2012-05-23T08:01:01Z"
+ },
+ "author": {
+ "id": 1,
+ "email": "john@example.com",
+ "name": "John Smith",
+ "blocked": false,
+ "created_at": "2012-05-23T08:00:58Z"
+ },
+ "closed": false,
+ "updated_at": "2012-07-12T13:43:19Z",
+ "created_at": "2012-06-28T12:58:06Z"
+}
+```
+
+## New issue
+
+Create a new project issue.
+
+```
+POST /projects/:id/issues
+```
+
+Parameters:
+
++ `id` (required) - The code name of a project
++ `title` (required) - The title of an issue
++ `description` (optional) - The description of an issue
++ `assignee_id` (optional) - The ID of a user to assign issue
++ `milestone_id` (optional) - The ID of a milestone to assign issue
++ `labels` (optional) - Comma-separated label names for an issue
+
+Will return created issue with status `201 Created` on success, or `404 Not found` on fail.
+
+## Edit issue
+
+Update an existing project issue.
+
+```
+PUT /projects/:id/issues/:issue_id
+```
+
+Parameters:
+
++ `id` (required) - The code name of a project
++ `issue_id` (required) - The ID of a project's issue
++ `title` (optional) - The title of an issue
++ `description` (optional) - The description of an issue
++ `assignee_id` (optional) - The ID of a user to assign issue
++ `milestone_id` (optional) - The ID of a milestone to assign issue
++ `labels` (optional) - Comma-separated label names for an issue
++ `closed` (optional) - The state of an issue (0 = false, 1 = true)
+
+Will return updated issue with status `200 OK` on success, or `404 Not found` on fail.
+
+## Delete issue
+
+Delete existing project issue.
+
+```
+DELETE /projects/:id/issues/:issue_id
+```
+
+Parameters:
+
++ `id` (required) - The code name of a project
++ `issue_id` (required) - The ID of a project's issue
+
+Status code `200` will be returned on success.
diff --git a/lib/api.rb b/lib/api.rb
index e24e0a78f71..6a8a3d651c0 100644
--- a/lib/api.rb
+++ b/lib/api.rb
@@ -15,5 +15,6 @@ module Gitlab
mount Users
mount Projects
+ mount Issues
end
end
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 35ad4d430ad..e5095f7189e 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -16,11 +16,7 @@ module Gitlab
expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :created_at
end
- class ProjectRepositoryBranches < Grape::Entity
- expose :name, :commit
- end
-
- class ProjectRepositoryTags < Grape::Entity
+ class RepoObject < Grape::Entity
expose :name, :commit
end
@@ -29,5 +25,17 @@ module Gitlab
expose :author, :using => Entities::UserBasic
expose :expires_at, :updated_at, :created_at
end
+
+ class Milestone < Grape::Entity
+ expose :id, :title, :description, :due_date, :closed, :updated_at, :created_at
+ end
+
+ class Issue < Grape::Entity
+ expose :id, :title, :description
+ expose :label_list, :as => :labels
+ expose :milestone, :using => Entities::Milestone
+ expose :assignee, :author, :using => Entities::UserBasic
+ expose :closed, :updated_at, :created_at
+ end
end
end
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index 424a17b283c..e7b9a417b08 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -4,6 +4,10 @@ module Gitlab
@current_user ||= User.find_by_authentication_token(params[:private_token])
end
+ def user_project
+ @project ||= current_user.projects.find_by_code(params[:id])
+ end
+
def authenticate!
error!({'message' => '401 Unauthorized'}, 401) unless current_user
end
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
new file mode 100644
index 00000000000..2b6a1ac269d
--- /dev/null
+++ b/lib/api/issues.rb
@@ -0,0 +1,111 @@
+module Gitlab
+ # Issues API
+ class Issues < Grape::API
+ before { authenticate! }
+
+ resource :issues do
+ # Get currently authenticated user's issues
+ #
+ # Example Request:
+ # GET /issues
+ get do
+ present current_user.issues, :with => Entities::Issue
+ end
+ end
+
+ resource :projects do
+ # Get a list of project issues
+ #
+ # Parameters:
+ # id (required) - The code name of a project
+ # Example Request:
+ # GET /projects/:id/issues
+ get ":id/issues" do
+ present user_project.issues, :with => Entities::Issue
+ end
+
+ # Get a single project issue
+ #
+ # Parameters:
+ # id (required) - The code name of a project
+ # issue_id (required) - The ID of a project issue
+ # Example Request:
+ # GET /projects/:id/issues/:issue_id
+ get ":id/issues/:issue_id" do
+ @issue = user_project.issues.find(params[:issue_id])
+ present @issue, :with => Entities::Issue
+ end
+
+ # Create a new project issue
+ #
+ # Parameters:
+ # id (required) - The code name of a project
+ # title (required) - The title of an issue
+ # description (optional) - The description of an issue
+ # assignee_id (optional) - The ID of a user to assign issue
+ # milestone_id (optional) - The ID of a milestone to assign issue
+ # labels (optional) - The labels of an issue
+ # Example Request:
+ # POST /projects/:id/issues
+ post ":id/issues" do
+ @issue = user_project.issues.new(
+ :title => params[:title],
+ :description => params[:description],
+ :assignee_id => params[:assignee_id],
+ :milestone_id => params[:milestone_id],
+ :label_list => params[:labels]
+ )
+ @issue.author = current_user
+
+ if @issue.save
+ present @issue, :with => Entities::Issue
+ else
+ error!({'message' => '404 Not found'}, 404)
+ end
+ end
+
+ # Update an existing issue
+ #
+ # Parameters:
+ # id (required) - The code name of a project
+ # issue_id (required) - The ID of a project issue
+ # title (optional) - The title of an issue
+ # description (optional) - The description of an issue
+ # assignee_id (optional) - The ID of a user to assign issue
+ # milestone_id (optional) - The ID of a milestone to assign issue
+ # labels (optional) - The labels of an issue
+ # closed (optional) - The state of an issue (0 = false, 1 = true)
+ # Example Request:
+ # PUT /projects/:id/issues/:issue_id
+ put ":id/issues/:issue_id" do
+ @issue = user_project.issues.find(params[:issue_id])
+ parameters = {
+ :title => (params[:title] || @issue.title),
+ :description => (params[:description] || @issue.description),
+ :assignee_id => (params[:assignee_id] || @issue.assignee_id),
+ :milestone_id => (params[:milestone_id] || @issue.milestone_id),
+ :label_list => (params[:labels] || @issue.label_list),
+ :closed => (params[:closed] || @issue.closed)
+ }
+
+ if @issue.update_attributes(parameters)
+ present @issue, :with => Entities::Issue
+ else
+ error!({'message' => '404 Not found'}, 404)
+ end
+ end
+
+ # Delete a project issue
+ #
+ # Parameters:
+ # id (required) - The code name of a project
+ # issue_id (required) - The ID of a project issue
+ # Example Request:
+ # DELETE /projects/:id/issues/:issue_id
+ delete ":id/issues/:issue_id" do
+ @issue = user_project.issues.find(params[:issue_id])
+ @issue.destroy
+ end
+ end
+ end
+end
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 70f8fa2aa62..34d1c23676e 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -20,8 +20,7 @@ module Gitlab
# Example Request:
# GET /projects/:id
get ":id" do
- @project = current_user.projects.find_by_code(params[:id])
- present @project, :with => Entities::Project
+ present user_project, :with => Entities::Project
end
# Get a project repository branches
@@ -31,8 +30,7 @@ module Gitlab
# Example Request:
# GET /projects/:id/repository/branches
get ":id/repository/branches" do
- @project = current_user.projects.find_by_code(params[:id])
- present @project.repo.heads.sort_by(&:name), :with => Entities::ProjectRepositoryBranches
+ present user_project.repo.heads.sort_by(&:name), :with => Entities::RepoObject
end
# Get a project repository tags
@@ -42,8 +40,7 @@ module Gitlab
# Example Request:
# GET /projects/:id/repository/tags
get ":id/repository/tags" do
- @project = current_user.projects.find_by_code(params[:id])
- present @project.repo.tags.sort_by(&:name).reverse, :with => Entities::ProjectRepositoryTags
+ present user_project.repo.tags.sort_by(&:name).reverse, :with => Entities::RepoObject
end
# Get a project snippet
@@ -54,8 +51,7 @@ module Gitlab
# Example Request:
# GET /projects/:id/snippets/:snippet_id
get ":id/snippets/:snippet_id" do
- @project = current_user.projects.find_by_code(params[:id])
- @snippet = @project.snippets.find(params[:snippet_id])
+ @snippet = user_project.snippets.find(params[:snippet_id])
present @snippet, :with => Entities::ProjectSnippet
end
@@ -70,8 +66,7 @@ module Gitlab
# Example Request:
# POST /projects/:id/snippets
post ":id/snippets" do
- @project = current_user.projects.find_by_code(params[:id])
- @snippet = @project.snippets.new(
+ @snippet = user_project.snippets.new(
:title => params[:title],
:file_name => params[:file_name],
:expires_at => params[:lifetime],
@@ -98,8 +93,7 @@ module Gitlab
# Example Request:
# PUT /projects/:id/snippets/:snippet_id
put ":id/snippets/:snippet_id" do
- @project = current_user.projects.find_by_code(params[:id])
- @snippet = @project.snippets.find(params[:snippet_id])
+ @snippet = user_project.snippets.find(params[:snippet_id])
parameters = {
:title => (params[:title] || @snippet.title),
:file_name => (params[:file_name] || @snippet.file_name),
@@ -122,8 +116,7 @@ module Gitlab
# Example Request:
# DELETE /projects/:id/snippets/:snippet_id
delete ":id/snippets/:snippet_id" do
- @project = current_user.projects.find_by_code(params[:id])
- @snippet = @project.snippets.find(params[:snippet_id])
+ @snippet = user_project.snippets.find(params[:snippet_id])
@snippet.destroy
end
@@ -135,8 +128,7 @@ module Gitlab
# Example Request:
# GET /projects/:id/snippets/:snippet_id/raw
get ":id/snippets/:snippet_id/raw" do
- @project = current_user.projects.find_by_code(params[:id])
- @snippet = @project.snippets.find(params[:snippet_id])
+ @snippet = user_project.snippets.find(params[:snippet_id])
present @snippet.content
end
end
diff --git a/lib/gitlab/logger.rb b/lib/gitlab/logger.rb
index aff13baf67b..c3a19e71c10 100644
--- a/lib/gitlab/logger.rb
+++ b/lib/gitlab/logger.rb
@@ -10,6 +10,7 @@ module Gitlab
def self.read_latest
path = Rails.root.join("log/githost.log")
+ self.build unless File.exist?(path)
logs = File.read(path).split("\n")
end
diff --git a/spec/api/issues_spec.rb b/spec/api/issues_spec.rb
new file mode 100644
index 00000000000..d81a07e214b
--- /dev/null
+++ b/spec/api/issues_spec.rb
@@ -0,0 +1,71 @@
+require 'spec_helper'
+
+describe Gitlab::API do
+ let(:user) { Factory :user }
+ let!(:project) { Factory :project, :owner => user }
+ let!(:issue) { Factory :issue, :author => user, :assignee => user, :project => project }
+ before { project.add_access(user, :read) }
+
+ describe "GET /issues" do
+ it "should return authentication error" do
+ get "#{api_prefix}/issues"
+ response.status.should == 401
+ end
+
+ describe "authenticated GET /issues" do
+ it "should return an array of issues" do
+ get "#{api_prefix}/issues?private_token=#{user.private_token}"
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.first['title'].should == issue.title
+ end
+ end
+ end
+
+ describe "GET /projects/:id/issues" do
+ it "should return project issues" do
+ get "#{api_prefix}/projects/#{project.code}/issues?private_token=#{user.private_token}"
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.first['title'].should == issue.title
+ end
+ end
+
+ describe "GET /projects/:id/issues/:issue_id" do
+ it "should return a project issue by id" do
+ get "#{api_prefix}/projects/#{project.code}/issues/#{issue.id}?private_token=#{user.private_token}"
+ response.status.should == 200
+ json_response['title'].should == issue.title
+ end
+ end
+
+ describe "POST /projects/:id/issues" do
+ it "should create a new project issue" do
+ post "#{api_prefix}/projects/#{project.code}/issues?private_token=#{user.private_token}",
+ :title => 'new issue', :labels => 'label, label2'
+ response.status.should == 201
+ json_response['title'].should == 'new issue'
+ json_response['description'].should be_nil
+ json_response['labels'].should == ['label', 'label2']
+ end
+ end
+
+ describe "PUT /projects/:id/issues/:issue_id" do
+ it "should update a project issue" do
+ put "#{api_prefix}/projects/#{project.code}/issues/#{issue.id}?private_token=#{user.private_token}",
+ :title => 'updated title', :labels => 'label2', :closed => 1
+ response.status.should == 200
+ json_response['title'].should == 'updated title'
+ json_response['labels'].should == ['label2']
+ json_response['closed'].should be_true
+ end
+ end
+
+ describe "DELETE /projects/:id/issues/:issue_id" do
+ it "should delete a project issue" do
+ expect {
+ delete "#{api_prefix}/projects/#{project.code}/issues/#{issue.id}?private_token=#{user.private_token}"
+ }.to change { Issue.count }.by(-1)
+ end
+ end
+end