Commit 6074f631abe7403a6cd98fb4b6c7835b33dcf9f7

Authored by Rafael Manzo
2 parents 885f0fd6 779bfbf0

Merge pull request #153 from mezuro/close_issue25

Close issue25
Gemfile
... ... @@ -37,7 +37,7 @@ gem 'kalibro_gatekeeper_client', '~> 1.0.0'
37 37 gem "pg", "~> 0.17.0"
38 38  
39 39 # Twitter Bootstrap for layout
40   -gem 'twitter-bootstrap-rails', :git => 'git://github.com/seyhunak/twitter-bootstrap-rails.git'
  40 +gem 'twitter-bootstrap-rails', :git => 'https://github.com/seyhunak/twitter-bootstrap-rails.git'
41 41  
42 42 # Chart generation
43 43 gem "chart-js-rails", "~> 0.0.6"
... ...
Gemfile.lock
1 1 GIT
2   - remote: git://github.com/seyhunak/twitter-bootstrap-rails.git
  2 + remote: https://github.com/seyhunak/twitter-bootstrap-rails.git
3 3 revision: 3edf24de985d946f16a2781644289cfdc51ba95b
4 4 specs:
5 5 twitter-bootstrap-rails (3.2.0)
... ...
app/controllers/projects_controller.rb
... ... @@ -8,6 +8,7 @@ class ProjectsController < ApplicationController
8 8 # GET /projects/new
9 9 def new
10 10 @project = Project.new
  11 + @project_image = ProjectImage.new
11 12 end
12 13  
13 14 # GET /projects
... ... @@ -19,9 +20,11 @@ class ProjectsController < ApplicationController
19 20 # POST /projects
20 21 # POST /projects.json
21 22 def create
  23 + image_url = project_params.delete(:image_url)
22 24 @project = Project.new(project_params)
23 25 respond_to do |format|
24 26 create_and_redir(format)
  27 + ProjectImage.create(url: image_url, project_id: @project.id )
25 28 end
26 29 end
27 30  
... ... @@ -36,11 +39,12 @@ class ProjectsController < ApplicationController
36 39 # GET /projects/1/edit.json
37 40 def edit
38 41 set_project
39   - end
  42 + end
40 43  
41 44 def update
42 45 set_project
43   - if @project.update(project_params)
  46 + image_url = project_params.delete(:image_url)
  47 + if @project.update(project_params) && @project_image.update(url: image_url)
44 48 redirect_to(project_path(@project.id))
45 49 else
46 50 render "edit"
... ... @@ -60,26 +64,26 @@ class ProjectsController < ApplicationController
60 64 end
61 65  
62 66 private
63   - # Use callbacks to share common setup or constraints between actions.
64   - def set_project
65   - @project = Project.find(params[:id])
66   - end
67   -
68   - # Never trust parameters from the scary internet, only allow the white list through.
69   - def project_params
70   - params[:project]
71   - end
  67 + # Use callbacks to share common setup or constraints between actions.
  68 + def set_project
  69 + @project = Project.find(params[:id])
  70 + @project_image = ProjectImage.find_by_project_id(@project.id)
  71 + end
72 72  
73   - # Extracted code from create action
74   - def create_and_redir(format)
75   - if @project.save
76   - current_user.project_ownerships.create project_id: @project.id
  73 + # Never trust parameters from the scary internet, only allow the white list through.
  74 + def project_params
  75 + params[:project]
  76 + end
77 77  
78   - format.html { redirect_to project_path(@project.id), notice: 'Project was successfully created.' }
79   - format.json { render action: 'show', status: :created, location: @project }
80   - else
81   - format.html { render action: 'new' }
82   - format.json { render json: @project.errors, status: :unprocessable_entity }
83   - end
  78 + # Extracted code from create action
  79 + def create_and_redir(format)
  80 + if @project.save
  81 + current_user.project_ownerships.create project_id: @project.id
  82 + format.html { redirect_to project_path(@project.id), notice: 'Project was successfully created.' }
  83 + format.json { render action: 'show', status: :created, location: @project }
  84 + else
  85 + format.html { render action: 'new' }
  86 + format.json { render json: @project.errors, status: :unprocessable_entity }
84 87 end
  88 + end
85 89 end
... ...
app/models/module_result.rb
... ... @@ -23,4 +23,4 @@ class ModuleResult < KalibroGatekeeperClient::Entities::ModuleResult
23 23 def find_grade_by_metric_name(metric_results, name)
24 24 metric_results.each { |metric_result| return metric_result.value if metric_result.metric_configuration_snapshot.metric.name == name }
25 25 end
26   -end
27 26 \ No newline at end of file
  27 +end
... ...
app/models/project_image.rb 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +class ProjectImage < ActiveRecord::Base
  2 + belongs_to :project
  3 +end
... ...
app/views/projects/_form.html.erb
1 1 <%= form_for(@project, :html => { role: 'form' }) do |f| %>
2   -<%= render :partial => 'shared/form_errors', :locals => {:object => @project} %>
3   -
4   -<div class="row margin-left-none">
5   - <div class="form-table col-md-9">
6   - <div class="form-row">
7   - <div class="field-container">
8   - <%= f.label :name, class: 'control-label' %><br>
9   - <%= f.text_field :name, :required => true, class: 'text-field form-control' %>
  2 + <%= render :partial => 'shared/form_errors', :locals => {:object => @project} %>
  3 + <div class="row margin-left-none">
  4 + <div class="form-table col-md-9">
  5 + <div class="form-row">
  6 + <div class="field-container">
  7 + <%= f.label :name, class: 'control-label' %><br>
  8 + <%= f.text_field :name, :required => true, class: 'text-field form-control' %>
  9 + </div>
10 10 </div>
11   - </div>
12   -
13   - <div class="form-row">
14   - <div class="field-container">
15   - <%= f.label :description, class: 'control-label' %><br>
16   - <%= f.text_area :description, class: 'text-area form-control' %>
  11 + <div class="form-row">
  12 + <div class="field-container">
  13 + <%= f.label :description, class: 'control-label' %><br>
  14 + <%= f.text_area :description, class: 'text-area form-control' %>
  15 + </div>
  16 + </div>
  17 + <div class="form-row">
  18 + <div class="field-container">
  19 + <%= f.label "Image url", class: 'control-label' %><br>
  20 + <%= f.text_field :image_url, class: 'text-area', value: @project_image.nil? ? '#' : @project_image.url %>
  21 + </div>
17 22 </div>
18 23 </div>
19 24 </div>
20   -</div>
21   -<div class="row margin-left-none" style="margin-top: 20px">
22   - <%= f.submit 'Save', class: 'btn btn-primary' %>
23   - <%= link_to 'Back', projects_path, class: 'btn btn-default' %>
24   -</div>
  25 + <div class="row margin-left-none" style="margin-top: 20px">
  26 + <%= f.submit 'Save', class: 'btn btn-primary' %>
  27 + <%= link_to 'Back', projects_path, class: 'btn btn-default' %>
  28 + </div>
25 29 <% end %>
... ...
app/views/projects/edit.html.erb
... ... @@ -2,4 +2,4 @@
2 2 <h1>Edit Project</h1>
3 3 </div>
4 4  
5   -<%= render 'form' %>
6 5 \ No newline at end of file
  6 +<%= render 'form' %>
... ...
app/views/projects/show.html.erb
  1 +
1 2 <div class="page-header">
2   - <h1><%= @project.name %></h1>
  3 + <div class="row">
  4 + <div class="col-md-2">
  5 + <% if @project_image && !@project_image.url.empty? %>
  6 + <%= image_tag "#{@project_image.url}", size:"128x128" %>
  7 + <% else %>
  8 + <center><i class="fa fa-file-image-o fa-5x"></i></center><br />
  9 + No image available
  10 + <% end %>
  11 + </div>
  12 + <div class="col-md-10">
  13 + <h1><%= @project.name %></h1>
  14 + </div>
  15 + </div>
3 16 </div>
4 17  
5 18 <p>
... ...
config/kalibro_gatekeeper.yml.sample
1 1 # Configuration loaded only for production environment
2   -address: http://localhost:8080/KalibroService/
3 2 \ No newline at end of file
  3 +-address: http://localhost:8080/KalibroService/
... ...
config/kalibro_processor.yml.sample
1   -address: http://localhost:8082
2 1 \ No newline at end of file
  2 +address: http://localhost:8082
... ...
db/migrate/20141006232631_create_project_images.rb 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +class CreateProjectImages < ActiveRecord::Migration
  2 + def change
  3 + create_table :project_images do |t|
  4 + t.belongs_to :project
  5 + t.string :image_url
  6 +
  7 + t.timestamps
  8 + end
  9 + end
  10 +end
... ...
db/migrate/20141119173020_rename_project_image_image_url_to_url.rb 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +class RenameProjectImageImageUrlToUrl < ActiveRecord::Migration
  2 + def change
  3 + change_table :project_images do |t|
  4 + t.rename :image_url, :url
  5 + end
  6 + end
  7 +end
... ...
db/schema.rb
... ... @@ -11,7 +11,7 @@
11 11 #
12 12 # It's strongly recommended that you check this file into your version control system.
13 13  
14   -ActiveRecord::Schema.define(version: 20140124124835) do
  14 +ActiveRecord::Schema.define(version: 20141119173020) do
15 15  
16 16 create_table "mezuro_configuration_ownerships", force: true do |t|
17 17 t.integer "user_id"
... ... @@ -20,6 +20,13 @@ ActiveRecord::Schema.define(version: 20140124124835) do
20 20 t.datetime "updated_at"
21 21 end
22 22  
  23 + create_table "project_images", force: true do |t|
  24 + t.integer "project_id"
  25 + t.string "url"
  26 + t.datetime "created_at"
  27 + t.datetime "updated_at"
  28 + end
  29 +
23 30 create_table "project_ownerships", force: true do |t|
24 31 t.integer "user_id"
25 32 t.integer "project_id"
... ...
features/project/deletion.feature
... ... @@ -22,6 +22,7 @@ Feature: Project Deletion
22 22 Given I am a regular user
23 23 And I am signed in
24 24 And I own a sample project
  25 + And I have a sample project_image
25 26 And I am at the Sample Project page
26 27 When I click the Destroy Project link
27 28 Then I should be in the All Projects page
... ...
features/project/edition.feature
... ... @@ -8,6 +8,7 @@ Feature: Project
8 8 Given I am a regular user
9 9 And I am signed in
10 10 And I own a sample project
  11 + And I have a sample project_image
11 12 And I am at the All Projects page
12 13 When I click the Edit link
13 14 Then I should be in the Edit Project page
... ... @@ -34,6 +35,7 @@ Feature: Project
34 35 Given I am a regular user
35 36 And I am signed in
36 37 And I own a sample project
  38 + And I have a sample project_image
37 39 And I am at the All Projects page
38 40 When I click the Edit link
39 41 Then The field "project[name]" should be filled with the sample project "name"
... ... @@ -44,6 +46,7 @@ Feature: Project
44 46 Given I am a regular user
45 47 And I am signed in
46 48 And I own a sample project
  49 + And I have a sample project_image
47 50 And I am at the sample project edit page
48 51 And I fill the Name field with "Kalibro"
49 52 And I fill the Description field with "Web Service to collect metrics"
... ... @@ -58,6 +61,7 @@ Feature: Project
58 61 And I have a project named "Qt-Calculator"
59 62 And I own a project named "Kalibro"
60 63 And I am at the sample project edit page
  64 + And I have a sample project_image
61 65 And I fill the Name field with "Qt-Calculator"
62 66 When I press the Save button
63 67 Then I should see "Name There is already a Project with name Qt-Calculator!"
... ... @@ -67,6 +71,7 @@ Feature: Project
67 71 Given I am a regular user
68 72 And I am signed in
69 73 And I own a sample project
  74 + And I have a sample project_image
70 75 And I am at the sample project edit page
71 76 And I fill the Description field with "Web Service to collect metrics"
72 77 When I press the Save button
... ... @@ -77,6 +82,7 @@ Feature: Project
77 82 Given I am a regular user
78 83 And I am signed in
79 84 And I own a sample project
  85 + And I have a sample project_image
80 86 And I am at the sample project edit page
81 87 And I fill the Name field with " "
82 88 When I press the Save button
... ...
features/project/listing.feature
... ... @@ -25,6 +25,7 @@ Feature: Project listing
25 25 Given I am a regular user
26 26 And I am signed in
27 27 And I have a sample project
  28 + And I have a sample project_image
28 29 And I am at the All Projects page
29 30 When I click the Show link
30 31 Then the sample project should be there
31 32 \ No newline at end of file
... ...
features/project/show.feature
... ... @@ -7,6 +7,7 @@ Feature: Show Project
7 7 Scenario: Should not show the create repository link to user that doesn't own the project
8 8 Given I am a regular user
9 9 And I have a sample project
  10 + And I have a sample project_image
10 11 And I have a sample configuration with native metrics
11 12 And I have a sample repository within the sample project
12 13 When I am at the Sample Project page
... ... @@ -19,6 +20,7 @@ Scenario: Should show the create repository link the project owner
19 20 Given I am a regular user
20 21 And I am signed in
21 22 And I own a sample project
  23 + And I have a sample project_image
22 24 When I am at the Sample Project page
23 25 Then I should see "New Repository"
24 26  
... ... @@ -26,6 +28,7 @@ Scenario: Should show the create repository link the project owner
26 28 @kalibro_processor_restart
27 29 Scenario: Considering the project has no repositories
28 30 Given I have a sample project
  31 + And I have a sample project_image
29 32 When I am at the Sample Project page
30 33 Then I should see "There are no Repositories yet!"
31 34  
... ... @@ -40,5 +43,6 @@ Scenario: Considering the project has repositories
40 43 @kalibro_processor_restart
41 44 Scenario: Checking project contents
42 45 Given I have a sample project
  46 + And I have a sample project_image
43 47 When I am at the Sample Project page
44 48 Then the sample project should be there
... ...
features/step_definitions/project_steps.rb
... ... @@ -8,6 +8,10 @@ Given(/^I have a sample project$/) do
8 8 @project = FactoryGirl.create(:project, {id: nil})
9 9 end
10 10  
  11 +Given(/^I have a sample project_image$/) do
  12 + @project_image = FactoryGirl.create(:project_image, {id: nil})
  13 +end
  14 +
11 15 Given(/^I have a project named "(.*?)"$/) do |name|
12 16 @project = FactoryGirl.create(:project, {id: nil, name: name})
13 17 end
... ...
spec/controllers/projects_controller_spec.rb
... ... @@ -18,10 +18,10 @@ describe ProjectsController, :type =&gt; :controller do
18 18 end
19 19  
20 20 context 'with valid fields' do
21   - let(:project) { FactoryGirl.build(:project) }
22   - let(:subject_params) { Hash[FactoryGirl.attributes_for(:project).map { |k,v| [k.to_s, v.to_s] }] } #FIXME: Mocha is creating the expectations with strings, but FactoryGirl returns everything with sybols and integers
  21 + let(:project) { FactoryGirl.build(:project) }
  22 + let(:subject_params) { Hash[FactoryGirl.attributes_for(:project).map { |k,v| [k.to_s, v.to_s] }] } #FIXME: Mocha is creating the expectations with strings, but FactoryGirl returns everything with sybols and integers
23 23  
24   - before :each do
  24 + before :each do
25 25 Project.any_instance.expects(:save).returns(true)
26 26 end
27 27  
... ... @@ -62,8 +62,8 @@ describe ProjectsController, :type =&gt; :controller do
62 62 end
63 63  
64 64 describe 'show' do
65   - subject { FactoryGirl.build(:project) }
66   - let(:repository) { FactoryGirl.build(:repository) }
  65 + subject { FactoryGirl.build(:project) }
  66 + let(:repository) { FactoryGirl.build(:repository) }
67 67 before :each do
68 68 Project.expects(:find).with(subject.id.to_s).returns(subject)
69 69 subject.expects(:repositories).returns(repository)
... ... @@ -116,7 +116,7 @@ describe ProjectsController, :type =&gt; :controller do
116 116 delete :destroy, :id => @subject.id
117 117 end
118 118  
119   - it { is_expected.to redirect_to(projects_path) }
  119 + it { is_expected.to redirect_to(projects_path) }
120 120 end
121 121 end
122 122  
... ... @@ -142,6 +142,7 @@ describe ProjectsController, :type =&gt; :controller do
142 142 describe 'edit' do
143 143 before do
144 144 @subject = FactoryGirl.build(:project)
  145 + @project_image = FactoryGirl.create(:project_image)
145 146 end
146 147  
147 148 context 'with an User logged in' do
... ... @@ -149,7 +150,6 @@ describe ProjectsController, :type =&gt; :controller do
149 150 @user = FactoryGirl.create(:user)
150 151 @ownership = FactoryGirl.build(:project_ownership)
151 152 @ownerships = []
152   -
153 153 User.any_instance.expects(:project_ownerships).at_least_once.returns(@ownerships)
154 154  
155 155 sign_in @user
... ... @@ -159,6 +159,7 @@ describe ProjectsController, :type =&gt; :controller do
159 159 before :each do
160 160 Project.expects(:find).with(@subject.id.to_s).returns(@subject)
161 161 @ownerships.expects(:find_by_project_id).with("#{@subject.id}").returns(@ownership)
  162 + ProjectImage.expects(:find_by_project_id).with(@subject.id).returns(@project_image)
162 163  
163 164 get :edit, :id => @subject.id
164 165 end
... ... @@ -194,8 +195,9 @@ describe ProjectsController, :type =&gt; :controller do
194 195  
195 196 describe 'update' do
196 197 before do
  198 + @project_image = FactoryGirl.build(:project_image)
197 199 @subject = FactoryGirl.build(:project)
198   - @subject_params = Hash[FactoryGirl.attributes_for(:project).map { |k,v| [k.to_s, v.to_s] }] #FIXME: Mocha is creating the expectations with strings, but FactoryGirl returns everything with sybols and integers
  200 + @subject_params = Hash[FactoryGirl.attributes_for(:project).map { |k,v| [k.to_s, v.to_s] }]
199 201 end
200 202  
201 203 context 'when the user is logged in' do
... ... @@ -207,9 +209,9 @@ describe ProjectsController, :type =&gt; :controller do
207 209 before do
208 210 @ownership = FactoryGirl.build(:project_ownership)
209 211 @ownerships = []
210   -
211 212 @ownerships.expects(:find_by_project_id).with("#{@subject.id}").returns(@ownership)
212 213 User.any_instance.expects(:project_ownerships).at_least_once.returns(@ownerships)
  214 + ProjectImage.expects(:find_by_project_id).with(@subject.id).returns(@project_image)
213 215 end
214 216  
215 217 context 'with valid fields' do
... ... @@ -221,7 +223,6 @@ describe ProjectsController, :type =&gt; :controller do
221 223 context 'rendering the show' do
222 224 before :each do
223 225 Project.expects(:exists?).returns(true)
224   -
225 226 post :update, :id => @subject.id, :project => @subject_params
226 227 end
227 228  
... ...
spec/factories/project_images.rb 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +# Read about factories at https://github.com/thoughtbot/factory_girl
  2 +
  3 +FactoryGirl.define do
  4 + factory :project_image do
  5 + project_id 1
  6 + url "Example"
  7 + end
  8 +
  9 + factory :project_no_image, class: ProjectImage do
  10 + url nil
  11 + end
  12 +end
... ...
spec/models/project_image_spec.rb 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +require 'rails_helper'
  2 +
  3 +RSpec.describe ProjectImage, :type => :model do
  4 + describe 'associations' do
  5 + it { is_expected.to belong_to(:project) }
  6 + end
  7 +end
... ...