Commit 254d1d7a authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'haynes/gitlab-ce-project_avatar' into 'master'

Project avatar

See merge request !1433
parents fae7b351 b92449c7
......@@ -34,7 +34,7 @@ v 7.8.0
-
-
-
-
- Add Project Avatars (Steven Thonus and Hannes Rosenögger)
-
-
- Password reset token validity increased from 2 hours to 2 days since it is also send on account creation.
......
......@@ -96,6 +96,7 @@ class Dispatcher
new Profile()
when 'projects'
new Project()
new ProjectAvatar()
switch path[1]
when 'edit'
shortcut_handler = new ShortcutsNavigation()
......
class @ProjectAvatar
constructor: ->
$('.js-choose-project-avatar-button').bind 'click', ->
form = $(this).closest('form')
form.find('.js-project-avatar-input').click()
$('.js-project-avatar-input').bind 'change', ->
form = $(this).closest('form')
filename = $(this).val().replace(/^.*[\\\/]/, '')
form.find('.js-avatar-filename').text(filename)
......@@ -23,3 +23,16 @@
&.s90 { width: 90px; height: 90px; margin-right: 15px; }
&.s160 { width: 160px; height: 160px; margin-right: 20px; }
}
.identicon {
text-align: center;
vertical-align: top;
&.s16 { font-size: 12px; line-height: 1.33; }
&.s24 { font-size: 14px; line-height: 1.8; }
&.s26 { font-size: 20px; line-height: 1.33; }
&.s32 { font-size: 24px; line-height: 1.33; }
&.s60 { font-size: 45px; line-height: 1.33; }
&.s90 { font-size: 68px; line-height: 1.33; }
&.s160 { font-size: 120px; line-height: 1.33; }
}
......@@ -75,6 +75,9 @@
}
}
}
.project-avatar {
float: left;
}
.project-description {
overflow: hidden;
......@@ -92,9 +95,12 @@
}
}
.dash-project-avatar {
float: left;
}
.dash-project-access-icon {
float: left;
margin-right: 3px;
margin-right: 5px;
width: 16px;
}
......
class Projects::AvatarsController < Projects::ApplicationController
layout 'project'
before_filter :project
def show
@blob = @project.repository.blob_at_branch('master', @project.avatar_in_git)
if @blob
headers['X-Content-Type-Options'] = 'nosniff'
send_data(
@blob.data,
type: @blob.mime_type,
disposition: 'inline',
filename: @blob.name
)
else
not_found!
end
end
def destroy
@project.remove_avatar!
@project.save
@project.reset_events_cache
redirect_to edit_project_path(@project)
end
end
......@@ -14,7 +14,7 @@ class ProjectsController < ApplicationController
end
def edit
render 'edit', layout: "project_settings"
render 'edit', layout: 'project_settings'
end
def create
......@@ -36,7 +36,7 @@ class ProjectsController < ApplicationController
format.html { redirect_to edit_project_path(@project), notice: 'Project was successfully updated.' }
format.js
else
format.html { render "edit", layout: "project_settings" }
format.html { render 'edit', layout: 'project_settings' }
format.js
end
end
......@@ -66,17 +66,17 @@ class ProjectsController < ApplicationController
format.html do
if @project.repository_exists?
if @project.empty_repo?
render "projects/empty", layout: user_layout
render 'projects/empty', layout: user_layout
else
@last_push = current_user.recent_push(@project.id) if current_user
render :show, layout: user_layout
end
else
render "projects/no_repo", layout: user_layout
render 'projects/no_repo', layout: user_layout
end
end
format.json { pager_json("events/_events", @events.count) }
format.json { pager_json('events/_events', @events.count) }
end
end
......@@ -87,9 +87,9 @@ class ProjectsController < ApplicationController
respond_to do |format|
format.html do
flash[:alert] = "Project deleted."
flash[:alert] = 'Project deleted.'
if request.referer.include?("/admin")
if request.referer.include?('/admin')
redirect_to admin_projects_path
else
redirect_to projects_dashboard_path
......@@ -141,7 +141,7 @@ class ProjectsController < ApplicationController
if link_to_image
format.json { render json: { link: link_to_image } }
else
format.json { render json: "Invalid file.", status: :unprocessable_entity }
format.json { render json: 'Invalid file.', status: :unprocessable_entity }
end
end
end
......@@ -172,14 +172,14 @@ class ProjectsController < ApplicationController
end
def user_layout
current_user ? "projects" : "public_projects"
current_user ? 'projects' : 'public_projects'
end
def project_params
params.require(:project).permit(
:name, :path, :description, :issues_tracker, :tag_list,
:issues_enabled, :merge_requests_enabled, :snippets_enabled, :issues_tracker_id, :default_branch,
:wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id
:wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :avatar
)
end
......
......@@ -50,6 +50,40 @@ module ApplicationHelper
args.any? { |v| v.to_s.downcase == action_name }
end
def project_icon(project_id, options = {})
project = Project.find_with_namespace(project_id)
if project.avatar.present?
image_tag project.avatar.url, options
elsif project.avatar_in_git
image_tag project_avatar_path(project), options
elsif options[:only_uploaded]
image_tag '/assets/no_project_icon.png', options
else # generated icon
project_identicon(project, options)
end
end
def project_identicon(project, options = {})
allowed_colors = {
red: 'FFEBEE',
purple: 'F3E5F5',
indigo: 'E8EAF6',
blue: 'E3F2FD',
teal: 'E0F2F1',
orange: 'FBE9E7',
gray: 'EEEEEE'
}
options[:class] ||= ''
options[:class] << ' identicon'
bg_key = project.id % 7
content_tag(:div, class: options[:class],
style: "background-color: ##{ allowed_colors.values[bg_key] }; color: #555") do
project.name[0, 1].upcase
end
end
def group_icon(group_path)
group = Group.find_by(path: group_path)
if group && group.avatar.present?
......@@ -82,24 +116,24 @@ module ApplicationHelper
if project.repo_exists?
time_ago_with_tooltip(project.repository.commit.committed_date)
else
"Never"
'Never'
end
rescue
"Never"
'Never'
end
def grouped_options_refs
repository = @project.repository
options = [
["Branches", repository.branch_names],
["Tags", VersionSorter.rsort(repository.tag_names)]
['Branches', repository.branch_names],
['Tags', VersionSorter.rsort(repository.tag_names)]
]
# If reference is commit id - we should add it to branch/tag selectbox
if(@ref && !options.flatten.include?(@ref) &&
@ref =~ /^[0-9a-zA-Z]{6,52}$/)
options << ["Commit", [@ref]]
options << ['Commit', [@ref]]
end
grouped_options_for_select(options, @ref || @project.default_branch)
......@@ -161,7 +195,7 @@ module ApplicationHelper
path = controller.controller_path.split('/')
namespace = path.first if path.second
[namespace, controller.controller_name, controller.action_name].compact.join(":")
[namespace, controller.controller_name, controller.action_name].compact.join(':')
end
# shortcut for gitlab config
......@@ -176,13 +210,13 @@ module ApplicationHelper
def search_placeholder
if @project && @project.persisted?
"Search in this project"
'Search in this project'
elsif @snippet || @snippets || @show_snippets
'Search snippets'
elsif @group && @group.persisted?
"Search in this group"
'Search in this group'
else
"Search"
'Search'
end
end
......@@ -193,7 +227,7 @@ module ApplicationHelper
def time_ago_with_tooltip(date, placement = 'top', html_class = 'time_ago')
capture_haml do
haml_tag :time, date.to_s,
class: html_class, datetime: date.getutc.iso8601, title: date.stamp("Aug 21, 2011 9:23pm"),
class: html_class, datetime: date.getutc.iso8601, title: date.stamp('Aug 21, 2011 9:23pm'),
data: { toggle: 'tooltip', placement: placement }
haml_tag :script, "$('." + html_class + "').timeago().tooltip()"
......@@ -216,8 +250,8 @@ module ApplicationHelper
end
def spinner(text = nil, visible = false)
css_class = "loading"
css_class << " hide" unless visible
css_class = 'loading'
css_class << ' hide' unless visible
content_tag :div, class: css_class do
content_tag(:i, nil, class: 'fa fa-spinner fa-spin') + text
......@@ -234,17 +268,17 @@ module ApplicationHelper
absolute_uri = nil
end
# Add "nofollow" only to external links
# Add 'nofollow' only to external links
if host && host != Gitlab.config.gitlab.host && absolute_uri
if html_options
if html_options[:rel]
html_options[:rel] << " nofollow"
html_options[:rel] << ' nofollow'
else
html_options.merge!(rel: "nofollow")
html_options.merge!(rel: 'nofollow')
end
else
html_options = Hash.new
html_options[:rel] = "nofollow"
html_options[:rel] = 'nofollow'
end
end
......
This diff is collapsed.
......@@ -14,6 +14,9 @@ module Projects
project.name = @from_project.name
project.path = @from_project.path
project.creator = @current_user
if @from_project.avatar.present? && @from_project.avatar.image?
project.avatar = @from_project.avatar
end
if namespace = @params[:namespace]
project.namespace = namespace
......@@ -39,16 +42,16 @@ module Projects
end
#Now fork the repo
unless gitlab_shell.fork_repository(@from_project.path_with_namespace, project.namespace.path)
raise "forking failed in gitlab-shell"
raise 'forking failed in gitlab-shell'
end
project.ensure_satellite_exists
end
rescue => ex
project.errors.add(:base, "Fork transaction failed.")
project.errors.add(:base, 'Fork transaction failed.')
project.destroy
end
else
project.errors.add(:base, "Invalid fork destination")
project.errors.add(:base, 'Invalid fork destination')
end
project
......
= link_to project_path(project), class: dom_class(project) do
.dash-project-access-icon
= visibility_level_icon(project.visibility_level)
.dash-project-avatar
= project_icon(project.to_param, alt: '', class: 'avatar s24')
%span.str-truncated
%span.namespace-name
- if project.namespace
......
......@@ -11,6 +11,8 @@
- @projects.each do |project|
%li.my-project-row
%h4.project-title
.project-avatar
= project_icon(project.to_param, alt: '', class: 'avatar s60')
.project-access-icon
= visibility_level_icon(project.visibility_level)
= link_to project_path(project), class: dom_class(project) do
......
......@@ -14,6 +14,8 @@
= link_to project_path(project), class: dom_class(project) do
.dash-project-access-icon
= visibility_level_icon(project.visibility_level)
.dash-project-avatar
= project_icon(project.to_param, alt: '', class: 'avatar s24')
%span.str-truncated
%span.project-name
= project.name
......
......@@ -2,6 +2,7 @@
.project-home-panel{:class => ("empty-project" if empty_repo)}
.project-home-row
.project-home-desc
= project_icon(@project.to_param, alt: '', class: 'avatar s32')
- if @project.description.present?
= escaped_autolink(@project.description)
- if can?(current_user, :admin_project, @project)
......
......@@ -7,7 +7,8 @@
%p.light Some settings, such as "Transfer Project", are hidden inside the danger area below.
%hr
.panel-body
= form_for @project, remote: true, html: { class: "edit_project form-horizontal" } do |f|
= form_for @project, remote: true, html: { multipart: true, class: "edit_project form-horizontal" }, authenticity_token: true do |f|
%fieldset
.form-group.project_name_holder
= f.label :name, class: 'control-label' do
......@@ -80,6 +81,34 @@
= f.check_box :snippets_enabled
%span.descr Share code pastes with others out of git repository
%fieldset.features
%legend
Project avatar:
.form-group
.col-sm-2
.col-sm-10
- if @project.avatar?
= project_icon(@project.to_param, alt: '', class: 'avatar s160')
- else
= project_icon(@project.to_param, alt: '', class: 'avatar s160', only_uploaded: true)
%p.light
- if @project.avatar_in_git
Project avatar in repository: #{ @project.avatar_in_git }
%p.light
- if @project.avatar?
You can change your project avatar here
- else
You can upload an project avatar here
%a.choose-btn.btn.btn-small.js-choose-project-avatar-button
%i.icon-paper-clip
%span Choose File ...
&nbsp;
%span.file_name.js-avatar-filename File name...
= f.file_field :avatar, class: "js-project-avatar-input hidden"
.light The maximum file size allowed is 200KB.
- if @project.avatar?
%hr
= link_to 'Remove avatar', project_avatar_path(@project), data: { confirm: "Project avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-avatar"
.form-actions
= f.submit 'Save changes', class: "btn btn-save"
......
......@@ -10,8 +10,8 @@ Gitlab::Application.routes.draw do
#
# Search
#
get 'search' => "search#show"
get 'search/autocomplete' => "search#autocomplete", as: :search_autocomplete
get 'search' => 'search#show'
get 'search/autocomplete' => 'search#autocomplete', as: :search_autocomplete
# API
API::API.logger Rails.logger
......@@ -20,9 +20,9 @@ Gitlab::Application.routes.draw do
# Get all keys of user
get ':username.keys' => 'profiles/keys#get_keys' , constraints: { username: /.*/ }
constraint = lambda { |request| request.env["warden"].authenticate? and request.env['warden'].user.admin? }
constraint = lambda { |request| request.env['warden'].authenticate? and request.env['warden'].user.admin? }
constraints constraint do
mount Sidekiq::Web, at: "/admin/sidekiq", as: :sidekiq
mount Sidekiq::Web, at: '/admin/sidekiq', as: :sidekiq
end
# Enable Grack support
......@@ -46,10 +46,10 @@ Gitlab::Application.routes.draw do
#
resources :snippets do
member do
get "raw"
get 'raw'
end
end
get "/s/:username" => "snippets#user_index", as: :user_snippets, constraints: { username: /.*/ }
get '/s/:username' => 'snippets#user_index', as: :user_snippets, constraints: { username: /.*/ }
#
# Github importer area
......@@ -72,12 +72,12 @@ Gitlab::Application.routes.draw do
end
resources :groups, only: [:index]
root to: "projects#trending"
root to: 'projects#trending'
end
# Compatibility with old routing
get 'public' => "explore/projects#index"
get 'public/projects' => "explore/projects#index"
get 'public' => 'explore/projects#index'
get 'public/projects' => 'explore/projects#index'
#
# Attachments serving
......@@ -122,7 +122,7 @@ Gitlab::Application.routes.draw do
resource :application_settings, only: [:show, :update]
root to: "dashboard#index"
root to: 'dashboard#index'
end
#
......@@ -163,7 +163,7 @@ Gitlab::Application.routes.draw do
#
# Dashboard Area
#
resource :dashboard, controller: "dashboard", only: [:show] do
resource :dashboard, controller: 'dashboard', only: [:show] do
member do
get :projects
get :issues
......@@ -194,12 +194,12 @@ Gitlab::Application.routes.draw do
devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations , passwords: :passwords, sessions: :sessions, confirmations: :confirmations }
devise_scope :user do
get "/users/auth/:provider/omniauth_error" => "omniauth_callbacks#omniauth_error", as: :omniauth_error
get '/users/auth/:provider/omniauth_error' => 'omniauth_callbacks#omniauth_error', as: :omniauth_error
end
#
# Project Area
#
resources :projects, constraints: { id: /[a-zA-Z.0-9_\-]+\/[a-zA-Z.0-9_\-]+/ }, except: [:new, :create, :index], path: "/" do
resources :projects, constraints: { id: /[a-zA-Z.0-9_\-]+\/[a-zA-Z.0-9_\-]+/ }, except: [:new, :create, :index], path: '/' do
member do
put :transfer
post :archive
......@@ -220,6 +220,7 @@ Gitlab::Application.routes.draw do
# Cannot be GET to differentiate from GET paths that end in preview.
post :preview, on: :member
end
resource :avatar, only: [:show, :destroy]
resources :new_tree, only: [:show, :update], constraints: {id: /.+/}, path: 'new'
resources :commit, only: [:show], constraints: {id: /[[:alnum:]]{6,40}/}
resources :commits, only: [:show], constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/}
......@@ -237,7 +238,7 @@ Gitlab::Application.routes.draw do
resources :snippets, constraints: {id: /\d+/} do
member do
get "raw"
get 'raw'
end
end
......@@ -249,7 +250,7 @@ Gitlab::Application.routes.draw do
end
member do
get "history"
get 'history'
end
end
......@@ -258,7 +259,7 @@ Gitlab::Application.routes.draw do
resource :repository, only: [:show, :create] do
member do
get "archive", constraints: { format: Gitlab::Regex.archive_formats_regex }
get 'archive', constraints: { format: Gitlab::Regex.archive_formats_regex }
end
end
......@@ -281,13 +282,13 @@ Gitlab::Application.routes.draw do
resources :refs, only: [] do
collection do
get "switch"
get 'switch'
end
member do
# tree viewer logs
get "logs_tree", constraints: { id: Gitlab::Regex.git_reference_regex }
get "logs_tree/:path" => "refs#logs_tree",
get 'logs_tree', constraints: { id: Gitlab::Regex.git_reference_regex }
get 'logs_tree/:path' => 'refs#logs_tree',
as: :logs_file,
constraints: {
id: Gitlab::Regex.git_reference_regex,
......@@ -353,10 +354,11 @@ Gitlab::Application.routes.draw do
delete :delete_attachment
end
end
end
end
get ':id' => "namespaces#show", constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/}
get ':id' => 'namespaces#show', constraints: {id: /(?:[^.]|\.(?!atom$))+/, format: /atom/}
root to: "dashboard#show"
root to: 'dashboard#show'
end
class AddAvatarToProjects < ActiveRecord::Migration
def change
add_column :projects, :avatar, :string
end
end
......@@ -327,6 +327,7 @@ ActiveRecord::Schema.define(version: 20150116234544) do
t.integer "star_count", default: 0, null: false
t.string "import_type"
t.string "import_source"
t.string "avatar"
end
add_index "projects", ["creator_id"], name: "index_projects_on_creator_id", using: :btree
......
......@@ -5,6 +5,19 @@ Feature: Project
And project "Shop" has push event
And I visit project "Shop" page
Scenario: I edit the project avatar
Given I visit edit project "Shop" page
When I change the project avatar
And I should see new project avatar
And I should see the "Remove avatar" button
Scenario: I remove the project avatar
Given I visit edit project "Shop" page
And I have an project avatar
When I remove my project avatar
Then I should see the default project avatar
And I should not see the "Remove avatar" button
@javascript
Scenario: I should see project activity
When I visit project "Shop" page
......
......@@ -17,17 +17,58 @@ class Spinach::Features::Project < Spinach::FeatureSteps
end
step 'change project path settings' do
fill_in "project_path", with: "new-path"
click_button "Rename"
fill_in 'project_path', with: 'new-path'
click_button 'Rename'
end
step 'I should see project with new path settings' do
project.path.should == "new-path"
project.path.should == 'new-path'
end
step 'I change the project avatar' do
attach_file(
:project_avatar,
File.join(Rails.root, 'public', 'gitlab_logo.png')
)
click_button 'Save changes'
@project.reload
end
step 'I should see new project avatar' do
@project.avatar.should be_instance_of AttachmentUploader
url = @project.avatar.url
url.should == "/uploads/project/avatar/#{ @project.id }/gitlab_logo.png"
end
step 'I should see the "Remove avatar" button' do
page.should have_link('Remove avatar')
end
step 'I have an project avatar' do
attach_file(
:project_avatar,
File.join(Rails.root, 'public', 'gitlab_logo.png')
)
click_button 'Save changes'
@project.reload
end
step 'I remove my project avatar' do
click_link 'Remove avatar'
@project.reload
end
step 'I should see the default project avatar' do
@project.avatar?.should be_false
end
step 'I should not see the "Remove avatar" button' do
page.should_not have_link('Remove avatar')
end
step 'I should see project "Shop" version' do
within '.project-side' do
page.should have_content "Version: 6.7.0.pre"
page.should have_content 'Version: 6.7.0.pre'
end
end
......@@ -45,12 +86,12 @@ class Spinach::Features::Project < Spinach::FeatureSteps
end
step 'I should see project "Forum" README' do
page.should have_link "README.md"
page.should have_content "Sample repo for testing gitlab features"
page.should have_link 'README.md'
page.should have_content 'Sample repo for testing gitlab features'
end
step 'I should see project "Shop" README' do
page.should have_link "README.md"
page.should have_content "testme"
page.should have_link 'README.md'
page.should have_content 'testme'
end
end
This diff is collapsed.
......@@ -14,7 +14,7 @@
# merge_requests_enabled :boolean default(TRUE), not null
# wiki_enabled :boolean default(TRUE), not null
# namespace_id :integer
# issues_tracker :string(255) default("gitlab"), not null
# issues_tracker :string(255) default('gitlab'), not null
# issues_tracker_id :string(255)
# snippets_enabled :boolean default(TRUE), not null
# last_activity_at :datetime
......@@ -26,12 +26,13 @@
# star_count :integer default(0), not null
# import_type :string(255)
# import_source :string(255)
# avatar :string(255)
#
require 'spec_helper'
describe Project do
describe "Associations" do
describe 'Associations' do
it { should belong_to(:group) }
it { should belong_to(:namespace) }
it { should belong_to(:creator).class_name('User') }
......@@ -52,10 +53,10 @@ describe Project do
it { should have_one(:pushover_service).dependent(:destroy) }
end
describe "Mass assignment" do
describe 'Mass assignment' do
end
describe "Validation" do
describe 'Validation' do
let!(:project) { create(:project) }
it { should validate_presence_of(:name) }
......@@ -70,7 +71,7 @@ describe Project do
it { should ensure_length_of(:issues_tracker_id).is_within(0..255) }
it { should validate_presence_of(:namespace) }
it "should not allow new projects beyond user limits" do
it 'should not allow new projects beyond user limits' do
project2 = build(:project)
project2.stub(:creator).and_return(double(can_create_project?: false, projects_limit: 0).as_null_object)
project2.should_not be_valid
......@@ -78,7 +79,7 @@ describe Project do
end
end
describe "Respond to" do
describe 'Respond to' do
it { should respond_to(:url_to_repo) }
it { should respond_to(:repo_exists?) }
it { should respond_to(:satellite) }
......@@ -89,27 +90,27 @@ describe Project do
it { should respond_to(:path_with_namespace) }
end
it "should return valid url to repo" do
project = Project.new(path: "somewhere")
project.url_to_repo.should == Gitlab.config.gitlab_shell.ssh_path_prefix + "somewhere.git"
it 'should return valid url to repo' do
project = Project.new(path: 'somewhere')
project.url_to_repo.should == Gitlab.config.gitlab_shell.ssh_path_prefix + 'somewhere.git'
end
it "returns the full web URL for this repo" do
project = Project.new(path: "somewhere")
it 'returns the full web URL for this repo' do
project = Project.new(path: 'somewhere')
project.web_url.should == "#{Gitlab.config.gitlab.url}/somewhere"
end
it "returns the web URL without the protocol for this repo" do
project = Project.new(path: "somewhere")
project.web_url_without_protocol.should == "#{Gitlab.config.gitlab.url.split("://")[1]}/somewhere"
it 'returns the web URL without the protocol for this repo' do
project = Project.new(path: 'somewhere')
project.web_url_without_protocol.should == "#{Gitlab.config.gitlab.url.split('://')[1]}/somewhere"
end
describe "last_activity methods" do
describe 'last_activity methods' do
let(:project) { create(:project) }
let(:last_event) { double(created_at: Time.now) }
describe "last_activity" do
it "should alias last_activity to last_event" do
describe 'last_activity' do
it 'should alias last_activity to last_event' do
project.stub(last_event: last_event)
project.last_activity.should == last_event
end
......@@ -134,13 +135,13 @@ describe Project do
let(:prev_commit_id) { merge_request.commits.last.id }
let(:commit_id) { merge_request.commits.first.id }
it "should close merge request if last commit from source branch was pushed to target branch" do
it 'should close merge request if last commit from source branch was pushed to target branch' do
project.update_merge_requests(prev_commit_id, commit_id, "refs/heads/#{merge_request.target_branch}", key.user)
merge_request.reload
merge_request.merged?.should be_true
end
it "should update merge request commits with new one if pushed to source branch" do
it 'should update merge request commits with new one if pushed to source branch' do
project.update_merge_requests(prev_commit_id, commit_id, "refs/heads/#{merge_request.source_branch}", key.user)
merge_request.reload
merge_request.last_commit.id.should == commit_id
......@@ -166,14 +167,14 @@ describe Project do
@project = create(:project, name: 'gitlabhq', namespace: @group)
end
it { @project.to_param.should == "gitlab/gitlabhq" }
it { @project.to_param.should == 'gitlab/gitlabhq' }
end
end
describe :repository do
let(:project) { create(:project) }
it "should return valid repo" do
it 'should return valid repo' do
project.repository.should be_kind_of(Repository)
end
end
......@@ -184,15 +185,15 @@ describe Project do
let(:not_existed_issue) { create(:issue) }
let(:ext_project) { create(:redmine_project) }
it "should be true or if used internal tracker and issue exists" do
it 'should be true or if used internal tracker and issue exists' do
project.issue_exists?(existed_issue.iid).should be_true
end
it "should be false or if used internal tracker and issue not exists" do
it 'should be false or if used internal tracker and issue not exists' do
project.issue_exists?(not_existed_issue.iid).should be_false
end
it "should always be true if used other tracker" do
it 'should always be true if used other tracker' do
ext_project.issue_exists?(rand(100)).should be_true
end
end
......@@ -201,11 +202,11 @@ describe Project do
let(:project) { create(:project) }
let(:ext_project) { create(:redmine_project) }
it "should be true if used internal tracker" do
it 'should be true if used internal tracker' do
project.used_default_issues_tracker?.should be_true
end
it "should be false if used other tracker" do
it 'should be false if used other tracker' do
ext_project.used_default_issues_tracker?.should be_false
end
end
......@@ -214,15 +215,15 @@ describe Project do
let(:project) { create(:project) }
let(:ext_project) { create(:redmine_project) }
it "should be true for projects with external issues tracker if issues enabled" do
it 'should be true for projects with external issues tracker if issues enabled' do
ext_project.can_have_issues_tracker_id?.should be_true
end
it "should be false for projects with internal issue tracker if issues enabled" do
it 'should be false for projects with internal issue tracker if issues enabled' do
project.can_have_issues_tracker_id?.should be_false
end
it "should be always false if issues disabled" do
it 'should be always false if issues disabled' do
project.issues_enabled = false
ext_project.issues_enabled = false
......@@ -310,4 +311,18 @@ describe Project do
expect(project.star_count).to eq(0)
end
end
describe :avatar_type do
let(:project) { create(:project) }
it 'should be true if avatar is image' do
project.update_attribute(:avatar, 'uploads/avatar.png')
project.avatar_type.should be_true
end
it 'should be false if avatar is html page' do
project.update_attribute(:avatar, 'uploads/avatar.html')
project.avatar_type.should == ['only images allowed']
end
end
end
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment