parent
d3974d429c
commit
b541755eda
@ -1,35 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module Api |
||||
module V2 |
||||
|
||||
class ScenariosController < ScenariosController |
||||
|
||||
include ::Api::V2::ApiController |
||||
|
||||
def index |
||||
@scenarios = @project.scenarios |
||||
respond_to do |format| |
||||
format.api |
||||
end |
||||
end |
||||
|
||||
def show |
||||
@scenario = @project.scenarios.find(params[:id]) |
||||
respond_to do |format| |
||||
format.api |
||||
end |
||||
end |
||||
end |
||||
|
||||
end |
||||
end |
@ -1,92 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class ScenariosController < ApplicationController |
||||
unloadable |
||||
helper :timelines |
||||
|
||||
before_filter :disable_api |
||||
before_filter :find_project_by_project_id |
||||
before_filter :authorize |
||||
|
||||
accept_key_auth :index, :show |
||||
|
||||
def index |
||||
@scenarios = @project.scenarios |
||||
respond_to do |format| |
||||
format.html { render_404 } |
||||
end |
||||
end |
||||
|
||||
def show |
||||
@scenario = @project.scenarios.find(params[:id]) |
||||
respond_to do |format| |
||||
format.html { render_404 } |
||||
end |
||||
end |
||||
|
||||
|
||||
# Admin actions |
||||
|
||||
def new |
||||
@scenario = @project.scenarios.new(:name => l('timelines.new_scenario')) |
||||
end |
||||
|
||||
def create |
||||
@scenario = @project.scenarios.new(permitted_params.scenario) |
||||
|
||||
if @scenario.save |
||||
flash[:notice] = l(:notice_successful_create) |
||||
redirect_to project_settings_path |
||||
else |
||||
render :action => 'new' |
||||
end |
||||
end |
||||
|
||||
def edit |
||||
@scenario = @project.scenarios.find(params[:id]) |
||||
end |
||||
|
||||
def update |
||||
@scenario = @project.scenarios.find(params[:id]) |
||||
|
||||
if @scenario.update_attributes(permitted_params.scenario) |
||||
flash[:notice] = l(:notice_successful_update) |
||||
redirect_to project_settings_path |
||||
else |
||||
render :action => 'edit' |
||||
end |
||||
end |
||||
|
||||
def confirm_destroy |
||||
@scenario = @project.scenarios.find(params[:id]) |
||||
end |
||||
|
||||
def destroy |
||||
@scenario = @project.scenarios.find(params[:id]) |
||||
@scenario.destroy |
||||
|
||||
flash[:notice] = l(:notice_successful_delete) |
||||
redirect_to project_settings_path |
||||
end |
||||
|
||||
protected |
||||
|
||||
def project_settings_path |
||||
url_for(:controller => '/projects', :action => 'settings', :tab => 'timelines', :id => @project) |
||||
end |
||||
helper_method :project_settings_path |
||||
|
||||
def default_breadcrumb |
||||
[render_to_string(:inline => "<%= link_to(l(:label_settings), project_settings_path) %>").html_safe, |
||||
l('timelines.scenarios')] |
||||
end |
||||
end |
@ -1,54 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class AlternateDate < ActiveRecord::Base |
||||
unloadable |
||||
|
||||
self.table_name = 'alternate_dates' |
||||
|
||||
belongs_to :planning_element, :class_name => "PlanningElement", |
||||
:foreign_key => 'planning_element_id' |
||||
belongs_to :scenario, :class_name => "Scenario", |
||||
:foreign_key => 'scenario_id' |
||||
|
||||
# history-related = historic |
||||
scope :historic, :conditions => "#{self.table_name}.scenario_id IS NULL" |
||||
|
||||
# scenario-related = scenaric |
||||
scope :scenaric, :conditions => "#{self.table_name}.scenario_id IS NOT NULL" |
||||
|
||||
validates_presence_of :start_date, :due_date, :planning_element |
||||
|
||||
delegate :planning_element_type, :planning_element_type_id, :is_milestone?, :to => :planning_element |
||||
|
||||
attr_accessible :start_date, :due_date |
||||
|
||||
validate do |
||||
if self.due_date and self.start_date and self.due_date < self.start_date |
||||
errors.add :due_date, :greater_than_start_date |
||||
end |
||||
|
||||
if self.planning_element.present? and self.is_milestone? |
||||
if self.due_date and self.start_date and self.start_date != self.due_date |
||||
errors.add :due_date, :not_start_date |
||||
end |
||||
end |
||||
end |
||||
|
||||
def duration |
||||
if start_date >= due_date |
||||
1 |
||||
else |
||||
due_date - start_date + 1 |
||||
end |
||||
end |
||||
|
||||
end |
@ -1,48 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class PlanningElementScenario |
||||
unloadable |
||||
|
||||
attr_accessor :alternate_date |
||||
|
||||
def initialize(alternate_date) |
||||
raise ArgumentError, 'Please pass an actual alternate date' if alternate_date.nil? |
||||
|
||||
@alternate_date = alternate_date |
||||
end |
||||
|
||||
delegate :start_date, :start_date=, :due_date, :due_date=, |
||||
:scenario, :scenario_id, |
||||
:duration, :planning_element, |
||||
:valid?, :errors, |
||||
:to => :alternate_date |
||||
|
||||
delegate :name, :id, :to_param, :to => :scenario |
||||
|
||||
def _destroy |
||||
false |
||||
end |
||||
|
||||
def ==(other) |
||||
other.is_a?(self.class) && |
||||
other.alternate_date == @alternate_date |
||||
end |
||||
|
||||
def eql?(other) |
||||
other.class == self.class && |
||||
other.alternate_date == @alternate_date |
||||
end |
||||
|
||||
def hash |
||||
@alternate_date.hash |
||||
end |
||||
end |
@ -1,28 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class Scenario < ActiveRecord::Base |
||||
unloadable |
||||
|
||||
self.table_name = 'scenarios' |
||||
|
||||
include ActiveModel::ForbiddenAttributesProtection |
||||
|
||||
belongs_to :project |
||||
|
||||
has_many :alternate_dates, :class_name => 'AlternateDate', |
||||
:foreign_key => 'scenario_id', |
||||
:dependent => :delete_all |
||||
|
||||
validates_presence_of :name, :project |
||||
|
||||
validates_length_of :name, :maximum => 255, :unless => lambda { |e| e.name.blank? } |
||||
end |
@ -1,27 +0,0 @@ |
||||
<%#-- copyright |
||||
OpenProject is a project management system. |
||||
|
||||
Copyright (C) 2012-2013 the OpenProject Team |
||||
|
||||
This program is free software; you can redistribute it and/or |
||||
modify it under the terms of the GNU General Public License version 3. |
||||
|
||||
See doc/COPYRIGHT.rdoc for more details. |
||||
|
||||
++#%> |
||||
|
||||
<%= error_messages_for 'scenario' %> |
||||
|
||||
<fieldset class="timelines-scenario-properties"> |
||||
<legend><%= l('timelines.properties') %></legend> |
||||
|
||||
<p> |
||||
<label for="scenario_name"> |
||||
<%= Scenario.human_attribute_name(:name) %> |
||||
</label> |
||||
<%= f.text_field :name, :class => 'autofocus' %> |
||||
</p> |
||||
</fieldset> |
||||
|
||||
<%= submit_tag l(:button_save) %> |
||||
<%= link_to l(:button_cancel), project_settings_path %> |
@ -1,61 +0,0 @@ |
||||
<%#-- copyright |
||||
OpenProject is a project management system. |
||||
|
||||
Copyright (C) 2012-2013 the OpenProject Team |
||||
|
||||
This program is free software; you can redistribute it and/or |
||||
modify it under the terms of the GNU General Public License version 3. |
||||
|
||||
See doc/COPYRIGHT.rdoc for more details. |
||||
|
||||
++#%> |
||||
|
||||
<%# |
||||
Used from app/views/projects/settings/_timelines.html.erb |
||||
%> |
||||
<h3><%= Scenario.model_name.human %></h3> |
||||
|
||||
<div class='contextual timelines-for_previous_heading'> |
||||
<%= link_to(l("timelines.new_scenario"), |
||||
new_project_scenario_path(@project), |
||||
:title => l("timelines.new_scenario"), |
||||
:class => 'icon icon-add') %> |
||||
</div> |
||||
|
||||
<table class='list'> |
||||
<thead> |
||||
<tr> |
||||
<th colspan="2"><%= Scenario.human_attribute_name(:name) %></th> |
||||
<th><%= Scenario.human_attribute_name(:created_at) %></th> |
||||
<th><%= Scenario.human_attribute_name(:updated_at) %></th> |
||||
<th> <!-- Actions --></th> |
||||
</tr> |
||||
</thead> |
||||
|
||||
<tbody> |
||||
<% @project.scenarios.each do |scenario| %> |
||||
<tr class="<%= cycle('odd', 'even', :name => "scenario_table") %>"> |
||||
<td class="timelines-scenario-name"> |
||||
<%=h scenario.name %> |
||||
</td> |
||||
<td class="timelines-scenario-description"> |
||||
<%= l('timelines.used_in_x_planning_elements', :count => scenario.alternate_dates.count) %> |
||||
</td> |
||||
<td class="timelines-scenario-created_at"> |
||||
<%= timelines_time_tag(scenario.created_at) %> |
||||
</td> |
||||
<td class="timelines-scenario-updated_at"> |
||||
<%= timelines_time_tag(scenario.updated_at) %> |
||||
</td> |
||||
<td class="timelines-scenario-actions"> |
||||
<%= link_to l(:button_edit), |
||||
edit_project_scenario_path(@project, scenario), |
||||
:class => 'icon icon-edit' %> |
||||
<%= link_to l(:button_delete), |
||||
confirm_destroy_project_scenario_path(@project, scenario), |
||||
:class => 'icon icon-del' %> |
||||
</td> |
||||
</tr> |
||||
<% end %> |
||||
</tbody> |
||||
</table> |
@ -1,29 +0,0 @@ |
||||
<%#-- copyright |
||||
OpenProject is a project management system. |
||||
|
||||
Copyright (C) 2012-2013 the OpenProject Team |
||||
|
||||
This program is free software; you can redistribute it and/or |
||||
modify it under the terms of the GNU General Public License version 3. |
||||
|
||||
See doc/COPYRIGHT.rdoc for more details. |
||||
|
||||
++#%> |
||||
|
||||
<%= header_tags %> |
||||
|
||||
<h2> |
||||
<%=h @scenario.name %> |
||||
</h2> |
||||
|
||||
<%= form_for :scenario, |
||||
:url => project_scenario_url(@project, @scenario), |
||||
:html => {:method => 'delete'} do |f| %> |
||||
|
||||
<div class='flash warning'> |
||||
<%= l('timelines.really_delete_scenario') %> |
||||
</div> |
||||
|
||||
<%= submit_tag l(:button_delete) %> |
||||
<%= link_to l(:button_cancel), project_settings_path %> |
||||
<% end %> |
@ -1,24 +0,0 @@ |
||||
<%#-- copyright |
||||
OpenProject is a project management system. |
||||
|
||||
Copyright (C) 2012-2013 the OpenProject Team |
||||
|
||||
This program is free software; you can redistribute it and/or |
||||
modify it under the terms of the GNU General Public License version 3. |
||||
|
||||
See doc/COPYRIGHT.rdoc for more details. |
||||
|
||||
++#%> |
||||
|
||||
<%= header_tags %> |
||||
|
||||
<h2> |
||||
<%=h @scenario.name %> |
||||
</h2> |
||||
|
||||
<%= form_for :scenario, |
||||
:url => project_scenario_url(@project, @scenario), |
||||
:html => {:method => 'put'} do |f| %> |
||||
<%= render :partial => 'form', |
||||
:locals => {:f => f, :scenario => @scenario} %> |
||||
<% end %> |
@ -1,24 +0,0 @@ |
||||
<%#-- copyright |
||||
OpenProject is a project management system. |
||||
|
||||
Copyright (C) 2012-2013 the OpenProject Team |
||||
|
||||
This program is free software; you can redistribute it and/or |
||||
modify it under the terms of the GNU General Public License version 3. |
||||
|
||||
See doc/COPYRIGHT.rdoc for more details. |
||||
|
||||
++#%> |
||||
|
||||
<%= header_tags %> |
||||
|
||||
<h2> |
||||
<%= l('timelines.new_scenario') %> |
||||
</h2> |
||||
|
||||
<%= form_for :scenario, |
||||
:url => project_scenarios_url(@project), |
||||
:html => {:method => 'post'} do |f| %> |
||||
<%= render :partial => 'form', |
||||
:locals => {:f => f, :scenario => @scenario} %> |
||||
<% end %> |
@ -0,0 +1,48 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class RemoveAlternateDatesAndScenarios < ActiveRecord::Migration |
||||
def up |
||||
drop_table(:alternate_dates) |
||||
drop_table(:scenarios) |
||||
end |
||||
|
||||
def down |
||||
create_table(:scenarios) do |t| |
||||
t.column :name, :string, :null => false |
||||
t.column :description, :text |
||||
|
||||
t.belongs_to :project |
||||
|
||||
t.timestamps |
||||
end |
||||
|
||||
add_index :scenarios, :project_id |
||||
|
||||
create_table(:alternate_dates) do |t| |
||||
t.column :start_date, :date, :null => false |
||||
t.column :due_date, :date, :null => false |
||||
|
||||
t.belongs_to :scenario |
||||
t.belongs_to :planning_element |
||||
|
||||
t.timestamps |
||||
end |
||||
|
||||
add_index :alternate_dates, :planning_element_id |
||||
add_index :alternate_dates, :scenario_id |
||||
|
||||
add_index :alternate_dates, |
||||
[:updated_at, :planning_element_id, :scenario_id], |
||||
:unique => true, |
||||
:name => 'index_ad_on_updated_at_and_planning_element_id' |
||||
end |
||||
end |
@ -1,27 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class OpenProject::JournalFormatter::ScenarioDate < JournalFormatter::Datetime |
||||
unloadable |
||||
|
||||
private |
||||
|
||||
def label(key) |
||||
key_match = /^scenario_(\d+)_(start|due)_date$/.match(key) |
||||
|
||||
scenario = Scenario.find_by_id(key_match[1]) |
||||
|
||||
scenario_name = scenario ? scenario.name : l(:label_scenario_deleted) |
||||
|
||||
l(:"label_scenario_#{key_match[2]}_date", :title => scenario_name) |
||||
end |
||||
|
||||
end |
@ -1,171 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require File.expand_path('../../../../spec_helper', __FILE__) |
||||
|
||||
describe Api::V2::ScenariosController do |
||||
describe 'index.xml' do |
||||
describe 'w/o a given project' do |
||||
it 'renders a 404 Not Found page' do |
||||
get 'index', :format => 'xml' |
||||
|
||||
response.response_code.should == 404 |
||||
end |
||||
end |
||||
|
||||
describe 'w/ an unknown project' do |
||||
it 'renders a 404 Not Found page' do |
||||
get 'index', :project_id => '4711', :format => 'xml' |
||||
|
||||
response.response_code.should == 404 |
||||
end |
||||
end |
||||
|
||||
describe 'w/ a known project' do |
||||
let(:project) { FactoryGirl.create(:project, :identifier => 'test_project') } |
||||
|
||||
describe 'w/o any scenarios within the project' do |
||||
it 'assigns an empty scenarios array' do |
||||
get 'index', :project_id => project.id, :format => 'xml' |
||||
assigns(:scenarios).should == [] |
||||
end |
||||
|
||||
it 'renders the index builder template' do |
||||
get 'index', :project_id => project.id, :format => 'xml' |
||||
response.should render_template('scenarios/index', :formats => ["api"]) |
||||
end |
||||
end |
||||
|
||||
describe 'w/ 3 scenarios within the project' do |
||||
before do |
||||
@created_scenarios = [ |
||||
FactoryGirl.create(:scenario, :project_id => project.id), |
||||
FactoryGirl.create(:scenario, :project_id => project.id), |
||||
FactoryGirl.create(:scenario, :project_id => project.id) |
||||
] |
||||
end |
||||
|
||||
it 'assigns a scenarios array containing all three elements' do |
||||
get 'index', :project_id => project.id, :format => 'xml' |
||||
assigns(:scenarios).should =~ @created_scenarios |
||||
end |
||||
|
||||
it 'renders the index builder template' do |
||||
get 'index', :project_id => project.id, :format => 'xml' |
||||
response.should render_template('scenarios/index', :formats => ["api"]) |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe 'access control' do |
||||
describe 'with a private project' do |
||||
let(:project) { FactoryGirl.create(:project, :identifier => 'test_project', |
||||
:is_public => false) } |
||||
|
||||
def fetch |
||||
get 'index', :project_id => project.id, :format => 'xml' |
||||
end |
||||
it_should_behave_like "a controller action which needs project permissions" |
||||
end |
||||
|
||||
describe 'with a public project' do |
||||
let(:project) { FactoryGirl.create(:project, :identifier => 'test_project', |
||||
:is_public => true) } |
||||
|
||||
def fetch |
||||
get 'index', :project_id => project.id, :format => 'xml' |
||||
end |
||||
it_should_behave_like "a controller action with unrestricted access" |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe 'show.xml' do |
||||
describe 'w/o a valid scenario id' do |
||||
describe 'w/o a given project' do |
||||
it 'renders a 404 Not Found page' do |
||||
get 'show', :id => '4711', :format => 'xml' |
||||
|
||||
response.response_code.should == 404 |
||||
end |
||||
end |
||||
|
||||
describe 'w/ an unknown project' do |
||||
it 'renders a 404 Not Found page' do |
||||
get 'index', :project_id => '4711', :id => '1337', :format => 'xml' |
||||
|
||||
response.response_code.should == 404 |
||||
end |
||||
end |
||||
|
||||
describe 'w/ a known project' do |
||||
let(:project) { FactoryGirl.create(:project, :identifier => 'test_project') } |
||||
|
||||
it 'raises ActiveRecord::RecordNotFound errors' do |
||||
lambda do |
||||
get 'show', :project_id => project.id, :id => '1337', :format => 'xml' |
||||
end.should raise_error(ActiveRecord::RecordNotFound) |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe 'w/ a valid scenario id' do |
||||
let(:project) { FactoryGirl.create(:project, :identifier => 'test_project') } |
||||
let(:scenario) { FactoryGirl.create(:scenario, :project_id => project.id) } |
||||
|
||||
describe 'w/o a given project' do |
||||
it 'renders a 404 Not Found page' do |
||||
get 'show', :id => scenario.id, :format => 'xml' |
||||
|
||||
response.response_code.should == 404 |
||||
end |
||||
end |
||||
|
||||
describe 'w/ a known project' do |
||||
it 'assigns the scenario' do |
||||
get 'show', :project_id => project.id, :id => scenario.id, :format => 'xml' |
||||
assigns(:scenario).should == scenario |
||||
end |
||||
|
||||
it 'renders the index builder template' do |
||||
get 'index', :project_id => project.id, :id => scenario.id, :format => 'xml' |
||||
response.should render_template('scenarios/index', :formats => ["api"]) |
||||
end |
||||
end |
||||
|
||||
describe 'access control' do |
||||
describe 'with a private project' do |
||||
let(:project) { FactoryGirl.create(:project, :identifier => 'test_project', |
||||
:is_public => false) } |
||||
|
||||
def fetch |
||||
get 'index', :project_id => project.id, :id => scenario.id, :format => 'xml' |
||||
end |
||||
it_should_behave_like "a controller action which needs project permissions" |
||||
end |
||||
|
||||
describe 'with a public project' do |
||||
let(:project) { FactoryGirl.create(:project, :identifier => 'test_project', |
||||
:is_public => true) } |
||||
|
||||
def fetch |
||||
get 'index', :project_id => project.id, :id => scenario.id, :format => 'xml' |
||||
end |
||||
it_should_behave_like "a controller action with unrestricted access" |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
def project_settings_path(project) |
||||
{:controller => 'projects', :action => 'settings', :tab => 'timelines', :id => project} |
||||
end |
||||
end |
@ -1,94 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require File.expand_path('../../spec_helper', __FILE__) |
||||
|
||||
describe ScenariosController do |
||||
|
||||
describe 'new.html' do |
||||
let(:project) { FactoryGirl.create(:project, :is_public => false) } |
||||
|
||||
def fetch |
||||
get 'new', :project_id => project.id |
||||
end |
||||
let(:permission) { :edit_project } |
||||
it_should_behave_like "a controller action which needs project permissions" |
||||
end |
||||
|
||||
describe 'create.html' do |
||||
let(:project) { FactoryGirl.create(:project, :is_public => false) } |
||||
|
||||
def fetch |
||||
post 'create', :project_id => project.id, |
||||
:scenario => FactoryGirl.build(:scenario, |
||||
:project_id => project.id).attributes |
||||
end |
||||
let(:permission) { :edit_project } |
||||
def expect_redirect_to |
||||
project_settings_path(project) |
||||
end |
||||
it_should_behave_like "a controller action which needs project permissions" |
||||
end |
||||
|
||||
describe 'edit.html' do |
||||
let(:project) { FactoryGirl.create(:project, :is_public => false) } |
||||
let(:scenario) { FactoryGirl.create(:scenario, :project_id => project.id) } |
||||
|
||||
def fetch |
||||
get 'edit', :project_id => project.id, :id => scenario.id |
||||
end |
||||
let(:permission) { :edit_project } |
||||
it_should_behave_like "a controller action which needs project permissions" |
||||
end |
||||
|
||||
describe 'update.html' do |
||||
let(:project) { FactoryGirl.create(:project, :is_public => false) } |
||||
let(:scenario) { FactoryGirl.create(:scenario, :project_id => project.id) } |
||||
|
||||
def fetch |
||||
post 'update', :project_id => project.id, :id => scenario.id, :scenario => { "name" => "blubs" } |
||||
end |
||||
let(:permission) { :edit_project } |
||||
def expect_redirect_to |
||||
project_settings_path(project) |
||||
end |
||||
it_should_behave_like "a controller action which needs project permissions" |
||||
end |
||||
|
||||
describe 'confirm_destroy.html' do |
||||
let(:project) { FactoryGirl.create(:project, :is_public => false) } |
||||
let(:scenario) { FactoryGirl.create(:scenario, :project_id => project.id) } |
||||
|
||||
def fetch |
||||
get 'confirm_destroy', :project_id => project.id, :id => scenario.id |
||||
end |
||||
let(:permission) { :edit_project } |
||||
it_should_behave_like "a controller action which needs project permissions" |
||||
end |
||||
|
||||
describe 'destroy.html' do |
||||
let(:project) { FactoryGirl.create(:project, :is_public => false) } |
||||
let(:scenario) { FactoryGirl.create(:scenario, :project_id => project.id) } |
||||
|
||||
def fetch |
||||
post 'destroy', :project_id => project.id, :id => scenario.id |
||||
end |
||||
let(:permission) { :edit_project } |
||||
def expect_redirect_to |
||||
project_settings_path(project) |
||||
end |
||||
it_should_behave_like "a controller action which needs project permissions" |
||||
end |
||||
|
||||
def project_settings_path(project) |
||||
{:controller => 'projects', :action => 'settings', :tab => 'timelines', :id => project} |
||||
end |
||||
end |
@ -1,34 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
FactoryGirl.define do |
||||
factory(:alternate_date, :class => AlternateDate) do |
||||
sequence(:start_date) { |n| ((n - 1) * 7).days.since.to_date } |
||||
sequence(:due_date) { |n| (n * 7).days.since.to_date } |
||||
|
||||
planning_element { |e| e.association(:planning_element) } |
||||
end |
||||
end |
||||
|
||||
FactoryGirl.define do |
||||
factory(:alternate_scenaric_date, :parent => :alternate_date) do |d| |
||||
scenario { |e| e.association(:scenario) } |
||||
end |
||||
end |
||||
|
||||
FactoryGirl.define do |
||||
factory(:alternate_historic_date, :parent => :alternate_date) do |d| |
||||
scenario nil |
||||
|
||||
sequence(:created_at) { |n| n.weeks.ago.to_date } |
||||
sequence(:updated_at) { |n| n.weeks.ago.to_date } |
||||
end |
||||
end |
@ -1,19 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
FactoryGirl.define do |
||||
factory(:scenario, :class => Scenario) do |
||||
sequence(:name) { |n| "Scenario No. #{n}" } |
||||
sequence(:description) { |n| "Scenario No. #{n} would allow us to launch last week." } |
||||
|
||||
association :project |
||||
end |
||||
end |
@ -1,98 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper.rb") |
||||
|
||||
describe OpenProject::JournalFormatter::ScenarioDate do |
||||
|
||||
include ActionView::Helpers::TagHelper |
||||
# WARNING: the order of the modules is important to ensure that url_for of |
||||
# ActionController::UrlWriter is called and not the one of ActionView::Helpers::UrlHelper |
||||
|
||||
include ActionView::Helpers::UrlHelper |
||||
include Rails.application.routes.url_helpers |
||||
|
||||
include Redmine::I18n |
||||
|
||||
struct = Struct.new("TimelinesScenarioDateTestJournal", :id, :journaled) |
||||
|
||||
let(:klass) { OpenProject::JournalFormatter::ScenarioDate } |
||||
let(:journal_id) { 1 } |
||||
let(:scenario) { FactoryGirl.create(:scenario) } |
||||
let(:journal) do |
||||
Struct::TimelinesScenarioDateTestJournal.new(journal_id, scenario) |
||||
end |
||||
let(:instance) { klass.new(journal) } |
||||
let(:key) { "scenario_#{scenario.id}_#{date_type}_date" } |
||||
let(:date_type) { "start" } |
||||
|
||||
describe :render do |
||||
describe "WITH rendering the start date |
||||
WITH the first value beeing nil, and the second a date |
||||
WITH the scenario existing" do |
||||
let(:new_date) { Date.today } |
||||
let(:expected) { I18n.t(:text_journal_set_to, |
||||
:label => "<strong>#{ I18n.t(:"label_scenario_#{date_type}_date", :title => scenario.name) }</strong>", |
||||
:value => "<i>#{format_date(new_date)}</i>") } |
||||
|
||||
it { instance.render(key, [nil, new_date]).should == expected } |
||||
end |
||||
|
||||
describe "WITH rendering the due date |
||||
WITH the first value beeing nil, and the second a date |
||||
WITH the scenario existing" do |
||||
let(:new_date) { Date.today } |
||||
let(:date_type) { "due" } |
||||
let(:expected) { I18n.t(:text_journal_set_to, |
||||
:label => "<strong>#{ I18n.t(:"label_scenario_#{date_type}_date", :title => scenario.name) }</strong>", |
||||
:value => "<i>#{format_date(new_date)}</i>") } |
||||
|
||||
it { instance.render(key, [nil, new_date]).should == expected } |
||||
end |
||||
|
||||
describe "WITH rendering the start date |
||||
WITH the first value beeing a date, and the second a date |
||||
WITH the scenario existing" do |
||||
let(:old_date) { Date.today - 4.days } |
||||
let(:new_date) { Date.today } |
||||
let(:expected) { I18n.t(:text_journal_changed, |
||||
:label => "<strong>#{ I18n.t(:"label_scenario_#{date_type}_date", :title => scenario.name) }</strong>", |
||||
:new => "<i>#{format_date(new_date)}</i>", |
||||
:old => "<i>#{format_date(old_date)}</i>") } |
||||
|
||||
it { instance.render(key, [old_date, new_date]).should == expected } |
||||
end |
||||
|
||||
describe "WITH rendering the start date |
||||
WITH the first value beeing a date, and the second nil |
||||
WITH the scenario existing" do |
||||
let(:old_date) { Date.today - 4.days } |
||||
let(:expected) { I18n.t(:text_journal_deleted, |
||||
:label => "<strong>#{ I18n.t(:"label_scenario_#{date_type}_date", :title => scenario.name) }</strong>", |
||||
:old => "<strike><i>#{format_date(old_date)}</i></strike>") } |
||||
|
||||
it { instance.render(key, [old_date, nil]).should == expected } |
||||
end |
||||
|
||||
describe "WITH rendering the start date |
||||
WITH the first value beeing nil, and the second a date |
||||
WITH the scenario is deleted" do |
||||
let(:new_date) { Date.today } |
||||
let(:key) { "scenario_0_#{date_type}_date" } |
||||
let(:expected) { I18n.t(:text_journal_set_to, |
||||
:label => "<strong>#{ I18n.t(:"label_scenario_#{date_type}_date", |
||||
:title => I18n.t(:label_scenario_deleted)) }</strong>", |
||||
:value => "<i>#{format_date(new_date)}</i>") } |
||||
|
||||
it { instance.render(key, [nil, new_date]).should == expected } |
||||
end |
||||
end |
||||
end |
@ -1,156 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require File.expand_path('../../spec_helper', __FILE__) |
||||
|
||||
describe AlternateDate do |
||||
describe '- Relations ' do |
||||
describe '#project' do |
||||
it 'can read the planning_element w/ the help of the belongs_to association' do |
||||
planning_element = FactoryGirl.create(:planning_element) |
||||
alternate_date = FactoryGirl.create(:alternate_date, |
||||
:planning_element_id => planning_element.id) |
||||
|
||||
alternate_date.reload |
||||
|
||||
alternate_date.planning_element.should == planning_element |
||||
end |
||||
|
||||
it 'can read the scenario w/ the help of the belongs_to association' do |
||||
scenario = FactoryGirl.create(:scenario) |
||||
alternate_date = FactoryGirl.create(:alternate_date, |
||||
:scenario_id => scenario.id) |
||||
|
||||
alternate_date.reload |
||||
|
||||
alternate_date.scenario.should == scenario |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe '- Scopes ' do |
||||
describe '.historic' do |
||||
it 'contains only elements not belonging to a scenario' do |
||||
planning_element = FactoryGirl.create(:planning_element) |
||||
|
||||
# created automatically when creating the planning element |
||||
alternate_date1 = planning_element.alternate_dates.first |
||||
|
||||
scenario = FactoryGirl.create(:scenario) |
||||
alternate_date2 = FactoryGirl.create(:alternate_date, |
||||
:scenario_id => scenario.id, |
||||
:planning_element_id => planning_element.id) |
||||
|
||||
AlternateDate.historic.size.should == 1 |
||||
AlternateDate.historic.should be_include(alternate_date1) |
||||
AlternateDate.historic.should_not be_include(alternate_date2) |
||||
end |
||||
end |
||||
|
||||
describe '.scenaric' do |
||||
it 'contains only elements belonging to a scenario' do |
||||
planning_element = FactoryGirl.create(:planning_element) |
||||
|
||||
# created automatically when creating the planning element |
||||
alternate_date1 = planning_element.alternate_dates.first |
||||
|
||||
scenario = FactoryGirl.create(:scenario) |
||||
alternate_date2 = FactoryGirl.create(:alternate_date, |
||||
:scenario_id => scenario.id) |
||||
|
||||
AlternateDate.scenaric.size.should == 1 |
||||
AlternateDate.scenaric.should_not be_include(alternate_date1) |
||||
AlternateDate.scenaric.should be_include(alternate_date2) |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe '- Validations ' do |
||||
let(:attributes) { |
||||
{:planning_element_id => 1, |
||||
:start_date => Date.today, |
||||
:due_date => Date.today + 2.weeks} |
||||
} |
||||
|
||||
before { |
||||
FactoryGirl.create(:planning_element, :id => 1) |
||||
|
||||
ApplicationHelper.set_language_if_valid 'en' |
||||
} |
||||
|
||||
it { AlternateDate.new.tap { |ad| ad.send(:assign_attributes, attributes, :without_protection => true) }.should be_valid } |
||||
|
||||
describe 'start_date' do |
||||
it 'is invalid w/o a start_date' do |
||||
attributes[:start_date] = nil |
||||
alternate_date = AlternateDate.new.tap { |ad| ad.send(:assign_attributes, attributes, :without_protection => true) } |
||||
|
||||
alternate_date.should_not be_valid |
||||
|
||||
alternate_date.errors[:start_date].should be_present |
||||
alternate_date.errors[:start_date].should == ["can't be blank"] |
||||
end |
||||
end |
||||
|
||||
describe 'due_date' do |
||||
it 'is invalid w/o a due_date' do |
||||
attributes[:due_date] = nil |
||||
alternate_date = AlternateDate.new.tap { |ad| ad.send(:assign_attributes, attributes, :without_protection => true) } |
||||
|
||||
alternate_date.should_not be_valid |
||||
|
||||
alternate_date.errors[:due_date].should be_present |
||||
alternate_date.errors[:due_date].should == ["can't be blank"] |
||||
end |
||||
|
||||
it 'is invalid if start_date is after due_date' do |
||||
attributes[:start_date] = Date.today |
||||
attributes[:due_date] = Date.today - 1.week |
||||
alternate_date = AlternateDate.new.tap { |ad| ad.send(:assign_attributes, attributes, :without_protection => true) } |
||||
|
||||
alternate_date.should_not be_valid |
||||
|
||||
alternate_date.errors[:due_date].should be_present |
||||
alternate_date.errors[:due_date].should == ["must be greater than start date"] |
||||
end |
||||
|
||||
it 'is invalid if planning_element is milestone and due_date is not on start_date' do |
||||
type = FactoryGirl.build(:type, :is_milestone => true) |
||||
attributes[:start_date] = Date.today |
||||
attributes[:due_date] = Date.today + 1.week |
||||
attributes[:planning_element] = FactoryGirl.build(:planning_element, :type => type) |
||||
|
||||
alternate_date = AlternateDate.new.tap { |ad| ad.send(:assign_attributes, attributes, :without_protection => true) } |
||||
|
||||
alternate_date.should_not be_valid |
||||
|
||||
alternate_date.errors[:due_date].should be_present |
||||
alternate_date.errors[:due_date].should == ["is not on start date, although this is required for milestones"] |
||||
end |
||||
end |
||||
|
||||
describe 'planning_element' do |
||||
it 'is invalid w/o a planning_element' do |
||||
attributes[:planning_element_id] = nil |
||||
alternate_date = AlternateDate.new.tap { |ad| ad.send(:assign_attributes, attributes, :without_protection => true) } |
||||
|
||||
alternate_date.should_not be_valid |
||||
|
||||
alternate_date.errors[:planning_element].should be_present |
||||
alternate_date.errors[:planning_element].should == ["can't be blank"] |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe ' - Instance Methods' do |
||||
it_should_behave_like "a model with non-negative duration" |
||||
end |
||||
end |
@ -1,62 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require File.expand_path('../../spec_helper', __FILE__) |
||||
|
||||
describe PlanningElementScenario do |
||||
let(:project) { FactoryGirl.build(:project) } |
||||
let(:planning_element) { FactoryGirl.build(:planning_element, :project => project) } |
||||
let(:scenario) { FactoryGirl.build(:scenario, :project => project) } |
||||
let(:alternate_date) { FactoryGirl.build(:alternate_date, :scenario => scenario, |
||||
:planning_element => planning_element) } |
||||
|
||||
let(:subject) { PlanningElementScenario.new(alternate_date) } |
||||
|
||||
it 'delegates start_date to the alternate date' do |
||||
subject.start_date.should == alternate_date.start_date |
||||
end |
||||
|
||||
it 'delegates start_date= to the alternate date' do |
||||
d = Date.new(1982, 01, 31) |
||||
subject.start_date = d |
||||
alternate_date.start_date.should == d |
||||
end |
||||
|
||||
it 'delegates due_date to the alternate date' do |
||||
subject.due_date.should == alternate_date.due_date |
||||
end |
||||
|
||||
it 'delegates due_date= to the alternate date' do |
||||
d = Date.new(1982, 01, 31) |
||||
subject.due_date = d |
||||
alternate_date.due_date.should == d |
||||
end |
||||
|
||||
it 'delegates duration to the alternate date' do |
||||
subject.duration.should eql alternate_date.duration |
||||
end |
||||
|
||||
it 'delegates scenario to the alternate date' do |
||||
subject.scenario.should == alternate_date.scenario |
||||
end |
||||
|
||||
it 'delegates scenario_id to the alternate date' do |
||||
subject.scenario_id.should == alternate_date.scenario_id |
||||
end |
||||
|
||||
it 'delegates name to the scenario' do |
||||
subject.name.should == scenario.name |
||||
end |
||||
|
||||
it 'delegates id to the scenario' do |
||||
subject.id.should == scenario.id |
||||
end |
||||
end |
@ -1,97 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require File.expand_path('../../spec_helper', __FILE__) |
||||
|
||||
describe Scenario do |
||||
describe '- Relations ' do |
||||
describe '#project' do |
||||
it 'can read the project w/ the help of the belongs_to association' do |
||||
project = FactoryGirl.create(:project) |
||||
scenario = FactoryGirl.create(:scenario, |
||||
:project_id => project.id) |
||||
|
||||
scenario.reload |
||||
|
||||
scenario.project.should == project |
||||
end |
||||
end |
||||
|
||||
describe '#alternate_dates' do |
||||
it 'can read alternate_dates w/ the help of the has_many association' do |
||||
scenario = FactoryGirl.create(:scenario) |
||||
alternate_date = FactoryGirl.create(:alternate_date, |
||||
:scenario_id => scenario.id) |
||||
|
||||
scenario.reload |
||||
|
||||
scenario.alternate_dates.size.should == 1 |
||||
scenario.alternate_dates.first.should == alternate_date |
||||
end |
||||
|
||||
it 'deletes associated alternate_dates' do |
||||
scenario = FactoryGirl.create(:scenario) |
||||
alternate_date = FactoryGirl.create(:alternate_date, |
||||
:scenario_id => scenario.id) |
||||
scenario.reload |
||||
|
||||
scenario.destroy |
||||
|
||||
expect { alternate_date.reload }.to raise_error(ActiveRecord::RecordNotFound) |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe '- Validations ' do |
||||
let(:attributes) { |
||||
{:name => 'Scenario No. 1', |
||||
:project_id => 1} |
||||
} |
||||
|
||||
before { FactoryGirl.create(:project, :id => 1) } |
||||
|
||||
it { Scenario.new.tap { |s| s.send(:assign_attributes, attributes, :without_protection => true) }.should be_valid } |
||||
|
||||
describe 'name' do |
||||
it 'is invalid w/o a name' do |
||||
attributes[:name] = nil |
||||
scenario = Scenario.new.tap { |s| s.send(:assign_attributes, attributes, :without_protection => true) } |
||||
|
||||
scenario.should_not be_valid |
||||
|
||||
scenario.errors[:name].should be_present |
||||
scenario.errors[:name].should == ["can't be blank"] |
||||
end |
||||
|
||||
it 'is invalid w/ a name longer than 255 characters' do |
||||
attributes[:name] = "A" * 500 |
||||
scenario = Scenario.new.tap { |s| s.send(:assign_attributes, attributes, :without_protection => true) } |
||||
|
||||
scenario.should_not be_valid |
||||
|
||||
scenario.errors[:name].should be_present |
||||
scenario.errors[:name].should == ["is too long (maximum is 255 characters)"] |
||||
end |
||||
end |
||||
|
||||
describe 'project' do |
||||
it 'is invalid w/o a project' do |
||||
attributes[:project_id] = nil |
||||
scenario = Scenario.new.tap { |s| s.send(:assign_attributes, attributes, :without_protection => true) } |
||||
|
||||
scenario.should_not be_valid |
||||
|
||||
scenario.errors[:project].should be_present |
||||
scenario.errors[:project].should == ["can't be blank"] |
||||
end |
||||
end |
||||
end |
||||
end |
@ -1,41 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
shared_examples_for "a model with non-negative duration" do |
||||
# it is assumed, that planning elements start on start_date 00:01 and end |
||||
# on due_date 23:59. Therefore, if start_date and due_date are on the very |
||||
# same day, the duration should be 1. |
||||
describe 'duration' do |
||||
describe 'when start date == end date' do |
||||
it 'is 1' do |
||||
subject.start_date = Date.today |
||||
subject.due_date = Date.today |
||||
subject.duration.should == 1 |
||||
end |
||||
end |
||||
|
||||
describe 'when end date > start date' do |
||||
it 'is the difference between end date and start date plus one day' do |
||||
subject.start_date = Date.today - 5.days |
||||
subject.due_date = Date.today |
||||
subject.duration.should == 6 |
||||
end |
||||
end |
||||
|
||||
describe 'when start date > end date' do |
||||
it 'is 1' do |
||||
subject.start_date = Date.today |
||||
subject.due_date = Date.today - 5.days |
||||
subject.duration.should == 1 |
||||
end |
||||
end |
||||
end |
||||
end |
@ -1,75 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require File.expand_path('../../../../../spec_helper', __FILE__) |
||||
|
||||
describe 'api/v2/scenarios/_scenario.api' do |
||||
before do |
||||
view.extend TimelinesHelper |
||||
end |
||||
|
||||
# added to pass in locals |
||||
def render |
||||
params[:format] = 'xml' |
||||
super(:partial => 'api/v2/scenarios/scenario.api', :object => scenario) |
||||
end |
||||
|
||||
describe 'with an assigned scenario' do |
||||
let(:project) { FactoryGirl.create(:project, :id => 4711, |
||||
:identifier => 'test_project', |
||||
:name => 'Test Project') } |
||||
let(:scenario) { FactoryGirl.build(:scenario, |
||||
:id => 1, |
||||
:project_id => project.id, |
||||
:name => 'Awesometastic scenario', |
||||
:description => 'Description of this scenario', |
||||
|
||||
:created_at => Time.parse('Thu Jan 06 12:35:00 +0100 2011'), |
||||
:updated_at => Time.parse('Fri Jan 07 12:35:00 +0100 2011')) } |
||||
|
||||
it 'renders a scenario node' do |
||||
render |
||||
response.should have_selector('scenario', :count => 1) |
||||
end |
||||
|
||||
describe 'scenario node' do |
||||
it 'contains an id element containing the scenario id' do |
||||
render |
||||
response.should have_selector('scenario id', :text => '1') |
||||
end |
||||
|
||||
it 'contains a project element containing the scenario\'s project id, identifier and name' do |
||||
render |
||||
response.should have_selector('scenario project[id="4711"][identifier="test_project"][name="Test Project"]') |
||||
end |
||||
|
||||
it 'contains an name element containing the scenario name' do |
||||
render |
||||
response.should have_selector('scenario name', :text => 'Awesometastic scenario') |
||||
end |
||||
|
||||
it 'contains an description element containing the scenario description' do |
||||
render |
||||
response.should have_selector('scenario description', :text => 'Description of this scenario') |
||||
end |
||||
|
||||
it 'contains a created_at element containing the scenario created_at in UTC in ISO 8601' do |
||||
render |
||||
response.should have_selector('scenario created_at', :text => '2011-01-06T11:35:00Z') |
||||
end |
||||
|
||||
it 'contains an updated_at element containing the scenario updated_at in UTC in ISO 8601' do |
||||
render |
||||
response.should have_selector('scenario updated_at', :text => '2011-01-07T11:35:00Z') |
||||
end |
||||
end |
||||
end |
||||
end |
@ -1,86 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require File.expand_path('../../../../../spec_helper', __FILE__) |
||||
|
||||
describe 'api/v2/scenarios/index.api.rsb' do |
||||
before do |
||||
view.extend TimelinesHelper |
||||
end |
||||
|
||||
before do |
||||
params[:format] = 'xml' |
||||
end |
||||
|
||||
describe 'with no scenarios available' do |
||||
it 'renders an empty scenarios document' do |
||||
assign(:scenarios, []) |
||||
|
||||
render |
||||
|
||||
response.should have_selector('scenarios', :count => 1) |
||||
response.should have_selector('scenarios[type=array][size="0"]') do |
||||
without_tag 'scenario' |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe 'with 3 scenarios available' do |
||||
let(:scenarios) do |
||||
[ |
||||
FactoryGirl.build(:scenario), |
||||
FactoryGirl.build(:scenario), |
||||
FactoryGirl.build(:scenario) |
||||
] |
||||
end |
||||
|
||||
it 'renders a scenarios document with the size 3 of array' do |
||||
assign(:scenarios, scenarios) |
||||
|
||||
render |
||||
|
||||
response.should have_selector('scenarios', :count => 1) |
||||
response.should have_selector('scenarios[type=array][size="3"]') |
||||
end |
||||
|
||||
it 'renders a scenario for each assigned scenario' do |
||||
assign(:scenarios, scenarios) |
||||
|
||||
render |
||||
|
||||
response.should have_selector('scenarios scenario', :count => 3) |
||||
end |
||||
|
||||
it 'renders the _scenario template for each assigned scenario' do |
||||
assign(:scenarios, scenarios) |
||||
|
||||
view.should_receive(:render).exactly(3).times.with(hash_including(:partial => '/api/v2/scenarios/scenario.api')).and_return('') |
||||
|
||||
# just to call the speced template despite the should receive expectations above |
||||
view.should_receive(:render).once.with({ :template=>"api/v2/scenarios/index", :handlers=>["rsb"], :formats=>["api"] }, {}).and_call_original |
||||
|
||||
render |
||||
end |
||||
|
||||
it 'passes the scenarios as local var to the partial' do |
||||
assign(:scenarios, scenarios) |
||||
|
||||
view.should_receive(:render).once.with(hash_including(:object => scenarios.first)).and_return('') |
||||
view.should_receive(:render).once.with(hash_including(:object => scenarios.second)).and_return('') |
||||
view.should_receive(:render).once.with(hash_including(:object => scenarios.third)).and_return('') |
||||
|
||||
# just to call the speced template despite the should receive expectations above |
||||
view.should_receive(:render).once.with({ :template=>"api/v2/scenarios/index", :handlers=>["rsb"], :formats=>["api"] }, {}).and_call_original |
||||
|
||||
render |
||||
end |
||||
end |
||||
end |
@ -1,56 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# |
||||
# Copyright (C) 2012-2013 the OpenProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# See doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require File.expand_path('../../../../../spec_helper', __FILE__) |
||||
|
||||
describe 'api/v2/scenarios/show.api.rsb' do |
||||
before do |
||||
view.extend TimelinesHelper |
||||
end |
||||
|
||||
before do |
||||
params[:format] = 'xml' |
||||
end |
||||
|
||||
describe 'with an assigned scenario' do |
||||
let(:scenario) { FactoryGirl.build(:scenario) } |
||||
|
||||
before do |
||||
assign(:scenario, scenario) |
||||
end |
||||
|
||||
it 'renders a scenario document' do |
||||
|
||||
render |
||||
|
||||
response.should have_selector('scenario', :count => 1) |
||||
end |
||||
|
||||
it 'renders the _scenario template once' do |
||||
view.should_receive(:render).once.with(hash_including(:partial => '/api/v2/scenarios/scenario.api')).and_return('') |
||||
|
||||
# just to render the speced template despite the should receive expectations above |
||||
view.should_receive(:render).once.with({:template=>"api/v2/scenarios/show", :handlers=>["rsb"], :formats=>["api"]}, {}).and_call_original |
||||
|
||||
render |
||||
end |
||||
|
||||
it 'passes the scenario as local var to the partial' do |
||||
|
||||
view.should_receive(:render).once.with(hash_including(:object => scenario)).and_return('') |
||||
|
||||
# just to render the speced template despite the should receive expectations above |
||||
view.should_receive(:render).once.with({:template=>"api/v2/scenarios/show", :handlers=>["rsb"], :formats=>["api"]}, {}).and_call_original |
||||
|
||||
render |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue