Commit 6074f631abe7403a6cd98fb4b6c7835b33dcf9f7

Authored by Rafael Manzo
2 parents 885f0fd6 779bfbf0

Merge pull request #153 from mezuro/close_issue25

Close issue25
@@ -37,7 +37,7 @@ gem 'kalibro_gatekeeper_client', '~> 1.0.0' @@ -37,7 +37,7 @@ gem 'kalibro_gatekeeper_client', '~> 1.0.0'
37 gem "pg", "~> 0.17.0" 37 gem "pg", "~> 0.17.0"
38 38
39 # Twitter Bootstrap for layout 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 # Chart generation 42 # Chart generation
43 gem "chart-js-rails", "~> 0.0.6" 43 gem "chart-js-rails", "~> 0.0.6"
1 GIT 1 GIT
2 - remote: git://github.com/seyhunak/twitter-bootstrap-rails.git 2 + remote: https://github.com/seyhunak/twitter-bootstrap-rails.git
3 revision: 3edf24de985d946f16a2781644289cfdc51ba95b 3 revision: 3edf24de985d946f16a2781644289cfdc51ba95b
4 specs: 4 specs:
5 twitter-bootstrap-rails (3.2.0) 5 twitter-bootstrap-rails (3.2.0)
app/controllers/projects_controller.rb
@@ -8,6 +8,7 @@ class ProjectsController < ApplicationController @@ -8,6 +8,7 @@ class ProjectsController < ApplicationController
8 # GET /projects/new 8 # GET /projects/new
9 def new 9 def new
10 @project = Project.new 10 @project = Project.new
  11 + @project_image = ProjectImage.new
11 end 12 end
12 13
13 # GET /projects 14 # GET /projects
@@ -19,9 +20,11 @@ class ProjectsController < ApplicationController @@ -19,9 +20,11 @@ class ProjectsController < ApplicationController
19 # POST /projects 20 # POST /projects
20 # POST /projects.json 21 # POST /projects.json
21 def create 22 def create
  23 + image_url = project_params.delete(:image_url)
22 @project = Project.new(project_params) 24 @project = Project.new(project_params)
23 respond_to do |format| 25 respond_to do |format|
24 create_and_redir(format) 26 create_and_redir(format)
  27 + ProjectImage.create(url: image_url, project_id: @project.id )
25 end 28 end
26 end 29 end
27 30
@@ -36,11 +39,12 @@ class ProjectsController < ApplicationController @@ -36,11 +39,12 @@ class ProjectsController < ApplicationController
36 # GET /projects/1/edit.json 39 # GET /projects/1/edit.json
37 def edit 40 def edit
38 set_project 41 set_project
39 - end 42 + end
40 43
41 def update 44 def update
42 set_project 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 redirect_to(project_path(@project.id)) 48 redirect_to(project_path(@project.id))
45 else 49 else
46 render "edit" 50 render "edit"
@@ -60,26 +64,26 @@ class ProjectsController < ApplicationController @@ -60,26 +64,26 @@ class ProjectsController < ApplicationController
60 end 64 end
61 65
62 private 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 end 87 end
  88 + end
85 end 89 end
app/models/module_result.rb
@@ -23,4 +23,4 @@ class ModuleResult < KalibroGatekeeperClient::Entities::ModuleResult @@ -23,4 +23,4 @@ class ModuleResult < KalibroGatekeeperClient::Entities::ModuleResult
23 def find_grade_by_metric_name(metric_results, name) 23 def find_grade_by_metric_name(metric_results, name)
24 metric_results.each { |metric_result| return metric_result.value if metric_result.metric_configuration_snapshot.metric.name == name } 24 metric_results.each { |metric_result| return metric_result.value if metric_result.metric_configuration_snapshot.metric.name == name }
25 end 25 end
26 -end  
27 \ No newline at end of file 26 \ No newline at end of file
  27 +end
app/models/project_image.rb 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +class ProjectImage < ActiveRecord::Base
  2 + belongs_to :project
  3 +end
app/views/projects/_form.html.erb
1 <%= form_for(@project, :html => { role: 'form' }) do |f| %> 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 </div> 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 </div> 22 </div>
18 </div> 23 </div>
19 </div> 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 <% end %> 29 <% end %>
app/views/projects/edit.html.erb
@@ -2,4 +2,4 @@ @@ -2,4 +2,4 @@
2 <h1>Edit Project</h1> 2 <h1>Edit Project</h1>
3 </div> 3 </div>
4 4
5 -<%= render 'form' %>  
6 \ No newline at end of file 5 \ No newline at end of file
  6 +<%= render 'form' %>
app/views/projects/show.html.erb
  1 +
1 <div class="page-header"> 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 </div> 16 </div>
4 17
5 <p> 18 <p>
config/kalibro_gatekeeper.yml.sample
1 # Configuration loaded only for production environment 1 # Configuration loaded only for production environment
2 -address: http://localhost:8080/KalibroService/  
3 \ No newline at end of file 2 \ No newline at end of file
  3 +-address: http://localhost:8080/KalibroService/
config/kalibro_processor.yml.sample
1 -address: http://localhost:8082  
2 \ No newline at end of file 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 @@ @@ -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 @@ @@ -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
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 # 11 #
12 # It's strongly recommended that you check this file into your version control system. 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 create_table "mezuro_configuration_ownerships", force: true do |t| 16 create_table "mezuro_configuration_ownerships", force: true do |t|
17 t.integer "user_id" 17 t.integer "user_id"
@@ -20,6 +20,13 @@ ActiveRecord::Schema.define(version: 20140124124835) do @@ -20,6 +20,13 @@ ActiveRecord::Schema.define(version: 20140124124835) do
20 t.datetime "updated_at" 20 t.datetime "updated_at"
21 end 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 create_table "project_ownerships", force: true do |t| 30 create_table "project_ownerships", force: true do |t|
24 t.integer "user_id" 31 t.integer "user_id"
25 t.integer "project_id" 32 t.integer "project_id"
features/project/deletion.feature
@@ -22,6 +22,7 @@ Feature: Project Deletion @@ -22,6 +22,7 @@ Feature: Project Deletion
22 Given I am a regular user 22 Given I am a regular user
23 And I am signed in 23 And I am signed in
24 And I own a sample project 24 And I own a sample project
  25 + And I have a sample project_image
25 And I am at the Sample Project page 26 And I am at the Sample Project page
26 When I click the Destroy Project link 27 When I click the Destroy Project link
27 Then I should be in the All Projects page 28 Then I should be in the All Projects page
features/project/edition.feature
@@ -8,6 +8,7 @@ Feature: Project @@ -8,6 +8,7 @@ Feature: Project
8 Given I am a regular user 8 Given I am a regular user
9 And I am signed in 9 And I am signed in
10 And I own a sample project 10 And I own a sample project
  11 + And I have a sample project_image
11 And I am at the All Projects page 12 And I am at the All Projects page
12 When I click the Edit link 13 When I click the Edit link
13 Then I should be in the Edit Project page 14 Then I should be in the Edit Project page
@@ -34,6 +35,7 @@ Feature: Project @@ -34,6 +35,7 @@ Feature: Project
34 Given I am a regular user 35 Given I am a regular user
35 And I am signed in 36 And I am signed in
36 And I own a sample project 37 And I own a sample project
  38 + And I have a sample project_image
37 And I am at the All Projects page 39 And I am at the All Projects page
38 When I click the Edit link 40 When I click the Edit link
39 Then The field "project[name]" should be filled with the sample project "name" 41 Then The field "project[name]" should be filled with the sample project "name"
@@ -44,6 +46,7 @@ Feature: Project @@ -44,6 +46,7 @@ Feature: Project
44 Given I am a regular user 46 Given I am a regular user
45 And I am signed in 47 And I am signed in
46 And I own a sample project 48 And I own a sample project
  49 + And I have a sample project_image
47 And I am at the sample project edit page 50 And I am at the sample project edit page
48 And I fill the Name field with "Kalibro" 51 And I fill the Name field with "Kalibro"
49 And I fill the Description field with "Web Service to collect metrics" 52 And I fill the Description field with "Web Service to collect metrics"
@@ -58,6 +61,7 @@ Feature: Project @@ -58,6 +61,7 @@ Feature: Project
58 And I have a project named "Qt-Calculator" 61 And I have a project named "Qt-Calculator"
59 And I own a project named "Kalibro" 62 And I own a project named "Kalibro"
60 And I am at the sample project edit page 63 And I am at the sample project edit page
  64 + And I have a sample project_image
61 And I fill the Name field with "Qt-Calculator" 65 And I fill the Name field with "Qt-Calculator"
62 When I press the Save button 66 When I press the Save button
63 Then I should see "Name There is already a Project with name Qt-Calculator!" 67 Then I should see "Name There is already a Project with name Qt-Calculator!"
@@ -67,6 +71,7 @@ Feature: Project @@ -67,6 +71,7 @@ Feature: Project
67 Given I am a regular user 71 Given I am a regular user
68 And I am signed in 72 And I am signed in
69 And I own a sample project 73 And I own a sample project
  74 + And I have a sample project_image
70 And I am at the sample project edit page 75 And I am at the sample project edit page
71 And I fill the Description field with "Web Service to collect metrics" 76 And I fill the Description field with "Web Service to collect metrics"
72 When I press the Save button 77 When I press the Save button
@@ -77,6 +82,7 @@ Feature: Project @@ -77,6 +82,7 @@ Feature: Project
77 Given I am a regular user 82 Given I am a regular user
78 And I am signed in 83 And I am signed in
79 And I own a sample project 84 And I own a sample project
  85 + And I have a sample project_image
80 And I am at the sample project edit page 86 And I am at the sample project edit page
81 And I fill the Name field with " " 87 And I fill the Name field with " "
82 When I press the Save button 88 When I press the Save button
features/project/listing.feature
@@ -25,6 +25,7 @@ Feature: Project listing @@ -25,6 +25,7 @@ Feature: Project listing
25 Given I am a regular user 25 Given I am a regular user
26 And I am signed in 26 And I am signed in
27 And I have a sample project 27 And I have a sample project
  28 + And I have a sample project_image
28 And I am at the All Projects page 29 And I am at the All Projects page
29 When I click the Show link 30 When I click the Show link
30 Then the sample project should be there 31 Then the sample project should be there
31 \ No newline at end of file 32 \ No newline at end of file
features/project/show.feature
@@ -7,6 +7,7 @@ Feature: Show Project @@ -7,6 +7,7 @@ Feature: Show Project
7 Scenario: Should not show the create repository link to user that doesn't own the project 7 Scenario: Should not show the create repository link to user that doesn't own the project
8 Given I am a regular user 8 Given I am a regular user
9 And I have a sample project 9 And I have a sample project
  10 + And I have a sample project_image
10 And I have a sample configuration with native metrics 11 And I have a sample configuration with native metrics
11 And I have a sample repository within the sample project 12 And I have a sample repository within the sample project
12 When I am at the Sample Project page 13 When I am at the Sample Project page
@@ -19,6 +20,7 @@ Scenario: Should show the create repository link the project owner @@ -19,6 +20,7 @@ Scenario: Should show the create repository link the project owner
19 Given I am a regular user 20 Given I am a regular user
20 And I am signed in 21 And I am signed in
21 And I own a sample project 22 And I own a sample project
  23 + And I have a sample project_image
22 When I am at the Sample Project page 24 When I am at the Sample Project page
23 Then I should see "New Repository" 25 Then I should see "New Repository"
24 26
@@ -26,6 +28,7 @@ Scenario: Should show the create repository link the project owner @@ -26,6 +28,7 @@ Scenario: Should show the create repository link the project owner
26 @kalibro_processor_restart 28 @kalibro_processor_restart
27 Scenario: Considering the project has no repositories 29 Scenario: Considering the project has no repositories
28 Given I have a sample project 30 Given I have a sample project
  31 + And I have a sample project_image
29 When I am at the Sample Project page 32 When I am at the Sample Project page
30 Then I should see "There are no Repositories yet!" 33 Then I should see "There are no Repositories yet!"
31 34
@@ -40,5 +43,6 @@ Scenario: Considering the project has repositories @@ -40,5 +43,6 @@ Scenario: Considering the project has repositories
40 @kalibro_processor_restart 43 @kalibro_processor_restart
41 Scenario: Checking project contents 44 Scenario: Checking project contents
42 Given I have a sample project 45 Given I have a sample project
  46 + And I have a sample project_image
43 When I am at the Sample Project page 47 When I am at the Sample Project page
44 Then the sample project should be there 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,6 +8,10 @@ Given(/^I have a sample project$/) do
8 @project = FactoryGirl.create(:project, {id: nil}) 8 @project = FactoryGirl.create(:project, {id: nil})
9 end 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 Given(/^I have a project named "(.*?)"$/) do |name| 15 Given(/^I have a project named "(.*?)"$/) do |name|
12 @project = FactoryGirl.create(:project, {id: nil, name: name}) 16 @project = FactoryGirl.create(:project, {id: nil, name: name})
13 end 17 end
spec/controllers/projects_controller_spec.rb
@@ -18,10 +18,10 @@ describe ProjectsController, :type =&gt; :controller do @@ -18,10 +18,10 @@ describe ProjectsController, :type =&gt; :controller do
18 end 18 end
19 19
20 context 'with valid fields' do 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 Project.any_instance.expects(:save).returns(true) 25 Project.any_instance.expects(:save).returns(true)
26 end 26 end
27 27
@@ -62,8 +62,8 @@ describe ProjectsController, :type =&gt; :controller do @@ -62,8 +62,8 @@ describe ProjectsController, :type =&gt; :controller do
62 end 62 end
63 63
64 describe 'show' do 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 before :each do 67 before :each do
68 Project.expects(:find).with(subject.id.to_s).returns(subject) 68 Project.expects(:find).with(subject.id.to_s).returns(subject)
69 subject.expects(:repositories).returns(repository) 69 subject.expects(:repositories).returns(repository)
@@ -116,7 +116,7 @@ describe ProjectsController, :type =&gt; :controller do @@ -116,7 +116,7 @@ describe ProjectsController, :type =&gt; :controller do
116 delete :destroy, :id => @subject.id 116 delete :destroy, :id => @subject.id
117 end 117 end
118 118
119 - it { is_expected.to redirect_to(projects_path) } 119 + it { is_expected.to redirect_to(projects_path) }
120 end 120 end
121 end 121 end
122 122
@@ -142,6 +142,7 @@ describe ProjectsController, :type =&gt; :controller do @@ -142,6 +142,7 @@ describe ProjectsController, :type =&gt; :controller do
142 describe 'edit' do 142 describe 'edit' do
143 before do 143 before do
144 @subject = FactoryGirl.build(:project) 144 @subject = FactoryGirl.build(:project)
  145 + @project_image = FactoryGirl.create(:project_image)
145 end 146 end
146 147
147 context 'with an User logged in' do 148 context 'with an User logged in' do
@@ -149,7 +150,6 @@ describe ProjectsController, :type =&gt; :controller do @@ -149,7 +150,6 @@ describe ProjectsController, :type =&gt; :controller do
149 @user = FactoryGirl.create(:user) 150 @user = FactoryGirl.create(:user)
150 @ownership = FactoryGirl.build(:project_ownership) 151 @ownership = FactoryGirl.build(:project_ownership)
151 @ownerships = [] 152 @ownerships = []
152 -  
153 User.any_instance.expects(:project_ownerships).at_least_once.returns(@ownerships) 153 User.any_instance.expects(:project_ownerships).at_least_once.returns(@ownerships)
154 154
155 sign_in @user 155 sign_in @user
@@ -159,6 +159,7 @@ describe ProjectsController, :type =&gt; :controller do @@ -159,6 +159,7 @@ describe ProjectsController, :type =&gt; :controller do
159 before :each do 159 before :each do
160 Project.expects(:find).with(@subject.id.to_s).returns(@subject) 160 Project.expects(:find).with(@subject.id.to_s).returns(@subject)
161 @ownerships.expects(:find_by_project_id).with("#{@subject.id}").returns(@ownership) 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 get :edit, :id => @subject.id 164 get :edit, :id => @subject.id
164 end 165 end
@@ -194,8 +195,9 @@ describe ProjectsController, :type =&gt; :controller do @@ -194,8 +195,9 @@ describe ProjectsController, :type =&gt; :controller do
194 195
195 describe 'update' do 196 describe 'update' do
196 before do 197 before do
  198 + @project_image = FactoryGirl.build(:project_image)
197 @subject = FactoryGirl.build(:project) 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 end 201 end
200 202
201 context 'when the user is logged in' do 203 context 'when the user is logged in' do
@@ -207,9 +209,9 @@ describe ProjectsController, :type =&gt; :controller do @@ -207,9 +209,9 @@ describe ProjectsController, :type =&gt; :controller do
207 before do 209 before do
208 @ownership = FactoryGirl.build(:project_ownership) 210 @ownership = FactoryGirl.build(:project_ownership)
209 @ownerships = [] 211 @ownerships = []
210 -  
211 @ownerships.expects(:find_by_project_id).with("#{@subject.id}").returns(@ownership) 212 @ownerships.expects(:find_by_project_id).with("#{@subject.id}").returns(@ownership)
212 User.any_instance.expects(:project_ownerships).at_least_once.returns(@ownerships) 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 end 215 end
214 216
215 context 'with valid fields' do 217 context 'with valid fields' do
@@ -221,7 +223,6 @@ describe ProjectsController, :type =&gt; :controller do @@ -221,7 +223,6 @@ describe ProjectsController, :type =&gt; :controller do
221 context 'rendering the show' do 223 context 'rendering the show' do
222 before :each do 224 before :each do
223 Project.expects(:exists?).returns(true) 225 Project.expects(:exists?).returns(true)
224 -  
225 post :update, :id => @subject.id, :project => @subject_params 226 post :update, :id => @subject.id, :project => @subject_params
226 end 227 end
227 228
spec/factories/project_images.rb 0 → 100644
@@ -0,0 +1,12 @@ @@ -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 @@ @@ -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