require 'rails_helper'
describe Plan do
include RolesHelper
include TemplateHelper
context "validations" do
it { is_expected.to validate_presence_of(:title) }
it { is_expected.to validate_presence_of(:template) }
it { is_expected.to allow_values(true, false).for(:feedback_requested) }
it { is_expected.not_to allow_value(nil).for(:feedback_requested) }
it { is_expected.to allow_values(true, false).for(:complete) }
it { is_expected.not_to allow_value(nil).for(:complete) }
end
context "associations" do
it { is_expected.to belong_to :template }
it { is_expected.to have_many :phases }
it { is_expected.to have_many :sections }
it { is_expected.to have_many :questions }
it { is_expected.to have_many :themes }
it { is_expected.to have_many :answers }
it { is_expected.to have_many :notes }
it { is_expected.to have_many :roles }
it { is_expected.to have_many :users }
it { is_expected.to have_many :exported_plans }
it { is_expected.to have_many :setting_objects }
end
describe ".publicly_visible" do
subject { Plan.publicly_visible }
context "when plan visibility is publicly_visible" do
let!(:plan) { create(:plan, :creator, :publicly_visible) }
it { is_expected.to include(plan) }
end
context "when plan visibility is organisationally_visible" do
let!(:plan) { create(:plan, :creator, :organisationally_visible) }
it { is_expected.not_to include(plan) }
end
context "when plan visibility is is_test" do
let!(:plan) { create(:plan, :creator, :is_test) }
it { is_expected.not_to include(plan) }
end
context "when plan visibility is privately_visible" do
let!(:plan) { create(:plan, :creator, :privately_visible) }
it { is_expected.not_to include(plan) }
end
end
describe ".organisationally_visible" do
subject { Plan.organisationally_visible }
context "when plan visibility is publicly_visible" do
let!(:plan) { create(:plan, :creator, :publicly_visible) }
it { is_expected.not_to include(plan) }
end
context "when plan visibility is organisationally_visible" do
let!(:plan) { create(:plan, :creator, :organisationally_visible) }
it { is_expected.to include(plan) }
end
context "when plan visibility is is_test" do
let!(:plan) { create(:plan, :creator, :is_test) }
it { is_expected.not_to include(plan) }
end
context "when plan visibility is privately_visible" do
let!(:plan) { create(:plan, :creator, :privately_visible) }
it { is_expected.not_to include(plan) }
end
end
describe ".privately_visible" do
subject { Plan.privately_visible }
context "when plan visibility is publicly_visible" do
let!(:plan) { create(:plan, :creator, :publicly_visible) }
it { is_expected.not_to include(plan) }
end
context "when plan visibility is organisationally_visible" do
let!(:plan) { create(:plan, :creator, :organisationally_visible) }
it { is_expected.not_to include(plan) }
end
context "when plan visibility is is_test" do
let!(:plan) { create(:plan, :creator, :is_test) }
it { is_expected.not_to include(plan) }
end
context "when plan visibility is privately_visible" do
let!(:plan) { create(:plan, :creator, :privately_visible) }
it { is_expected.to include(plan) }
end
end
describe ".organisationally_or_publicly_visible" do
let!(:user) { create(:user) }
subject { Plan.organisationally_or_publicly_visible(user) }
context "when user is creator" do
before do
create(:role, :creator, user: user, plan: plan)
end
let!(:plan) { create(:plan, :creator, :publicly_visible) }
it { is_expected.not_to include(plan) }
end
context "when user is administrator" do
before do
create(:role, :administrator, user: user, plan: plan)
end
let!(:plan) { create(:plan, :creator, :publicly_visible) }
it { is_expected.not_to include(plan) }
end
context "when user is commenter" do
before do
create(:role, :commenter, user: user, plan: plan)
end
let!(:plan) { create(:plan, :creator, :publicly_visible) }
it { is_expected.not_to include(plan) }
end
context "when user is editor" do
before do
create(:role, :editor, user: user, plan: plan)
end
let!(:plan) { create(:plan, :creator, :publicly_visible) }
it { is_expected.not_to include(plan) }
end
context "when plan visibility is publicly_visible" do
before do
new_user = create(:user, org: user.org)
create(:role, :creator, :administrator, :editor, :commenter,
user: new_user, plan: plan)
end
let!(:template) { build_template(1, 1, 1) }
let!(:plan) { create(:plan, :creator, :organisationally_visible, template: template) }
let!(:answer) { create(:answer, plan: plan,
question: template.phases.first.sections.first.questions.first) }
it "includes publicly_visible plans" do
is_expected.to include(plan)
end
end
context "when plan visibility is organisationally_visible" do
before do
new_user = create(:user, org: user.org)
create(:role, :creator, :administrator, :editor, :commenter,
user: new_user, plan: plan)
end
let!(:template) { build_template(1, 1, 1) }
let!(:plan) { create(:plan, :creator, :organisationally_visible, template: template) }
let!(:answer) { create(:answer, plan: plan,
question: template.phases.first.sections.first.questions.first) }
it "includes organisationally_visible plans" do
is_expected.to include(plan)
end
end
context "when plan is not complete" do
before do
new_user = create(:user, org: user.org)
create(:role, :creator, :administrator, :editor, :commenter,
user: new_user, plan: plan)
end
let!(:plan) { create(:plan, :creator, :organisationally_visible) }
it "includes organisationally_visible plans" do
is_expected.not_to include(plan)
end
end
context "when plan visibility is is_test" do
let!(:plan) { create(:plan, :creator, :is_test) }
it { is_expected.not_to include(plan) }
end
context "when plan visibility is privately_visible" do
let!(:plan) { create(:plan, :creator, :privately_visible) }
it { is_expected.not_to include(plan) }
end
context "when plan has no active roles" do
let!(:plan) { build_plan }
it "should not be included" do
plan.roles.inject{ |r| r.deactivate! }
is_expected.to_not include(plan)
end
end
end
describe ".is_test" do
subject { Plan.is_test }
context "when plan visibility is publicly_visible" do
let!(:plan) { create(:plan, :creator, :publicly_visible) }
it { is_expected.not_to include(plan) }
end
context "when plan visibility is organisationally_visible" do
let!(:plan) { create(:plan, :creator, :organisationally_visible) }
it { is_expected.not_to include(plan) }
end
context "when plan visibility is is_test" do
let!(:plan) { create(:plan, :creator, :is_test) }
it { is_expected.to include(plan) }
end
context "when plan visibility is privately_visible" do
let!(:plan) { create(:plan, :creator, :privately_visible) }
it { is_expected.not_to include(plan) }
end
end
describe ".active" do
let!(:plan) { create(:plan, :creator) }
let!(:user) { create(:user) }
subject { Plan.active(user) }
context "where user role is active" do
before do
create(:role, :active, :creator, user: user, plan: plan)
end
it { is_expected.to include(plan) }
end
context "where user role is not active" do
before do
create(:role, :inactive, :creator, user: user, plan: plan)
end
it { is_expected.not_to include(plan) }
end
end
describe ".load_for_phase" do
let!(:template) { create(:template) }
let!(:plan) { create(:plan, :creator, template: template) }
let!(:phase) { create(:phase, template: template) }
let!(:section) { create(:section, phase: phase) }
let!(:question) { create(:question, section: section) }
subject { Plan.load_for_phase(plan.id, phase.id) }
context "when Plan ID is valid and Phase ID is valid child" do
it "returns an Array" do
expect(subject).to be_an(Array)
end
it "returns the Plan first" do
expect(subject.first).to eql(plan)
end
it "returns the Phase second" do
expect(subject.second).to eql(phase)
end
end
context "when Plan ID is valid and Phase ID is not valid child" do
let!(:phase) { create(:phase) }
it "raises an exception" do
# TODO: This is not ideal behaviour. Fix this.
expect { subject }.to raise_error(NoMethodError)
end
end
context "when Plan ID is not valid" do
let!(:plan) { stub(id: 0) }
it "raises an exception" do
# TODO: This is not ideal behaviour. Fix this.
expect { subject }.to raise_error(NoMethodError)
end
end
end
describe ".deep_copy" do
let!(:plan) { create(:plan, :creator, answers: 2, guidance_groups: 2,
feedback_requested: true) }
subject { Plan.deep_copy(plan) }
it "prepends the title with 'Copy'" do
expect(subject.title).to include("Copy")
end
it "sets feedback_requested to false" do
expect(subject.feedback_requested).to eql(false)
end
it "copies the title from source" do
expect(subject.title).to include(plan.title)
end
it "persists the record" do
expect(subject).to be_persisted
end
it "creates new copies of the answers" do
expect(subject.answers).to have(2).items
end
it "duplicates the guidance groups" do
expect(subject.guidance_groups).to have(2).items
end
end
describe ".search" do
subject { Plan.search("foo") }
context "when Plan title matches term" do
let!(:plan) { create(:plan, title: "foolike title") }
it { is_expected.to include(plan) }
end
context "when Template title matches term" do
let!(:template) { create(:template, title: "foolike title") }
let!(:plan) { create(:plan, template: template) }
it { is_expected.to include(plan) }
end
context "when neither title matches term" do
let!(:plan) { create(:plan, description: "foolike desc") }
it { is_expected.not_to include(plan) }
end
end
describe "#answer" do
let!(:plan) { create(:plan, :creator, answers: 1) }
let!(:question) { create(:question) }
subject { plan.answer(question.id, create_if_missing) }
context "when create_if_missing is true and answer exists on the DB" do
let!(:create_if_missing) { true }
let!(:answer) { create(:answer, plan: plan, question: question) }
it "returns the existing Answer" do
expect(subject).to eql(answer)
end
end
context "when create_if_missing is true and answer doesn't exist on the DB" do
let!(:create_if_missing) { true }
it "returns a new Answer" do
expect(subject).to be_an(Answer)
end
it "doesn't persist the new Answer" do
expect(subject).to be_new_record
end
end
context "when create_if_missing is false and qid exists on the DB" do
let!(:create_if_missing) { false }
let!(:answer) { create(:answer, plan: plan, question: question) }
it "returns the existing Answer" do
expect(subject).to eql(answer)
end
end
context "when create_if_missing is false and qid doesn't exist on the DB" do
let!(:create_if_missing) { false }
let!(:answer) { nil }
it "returns nil" do
expect(subject).to be_nil
end
end
end
describe "#guidance_group_options" do
let!(:plan) { create(:plan, :creator) }
subject { plan.guidance_group_options }
before do
@phase = create(:phase, template: plan.template)
@section = create(:section, phase: @phase)
@question = create(:question, section: @section)
@theme = create(:theme)
@guidance = create(:guidance)
@guidance_group = @guidance.guidance_group
@question.themes << @theme
@theme.guidances << @guidance
end
context "when guidance groups are unpublished" do
before do
@guidance_group.update(published: false)
end
it "excludes the guidance group from options" do
expect(subject).not_to include(@guidance_group)
end
end
context "when guidance groups are published" do
it "includes the guidance group in options" do
expect(subject).to include(@guidance_group)
end
end
end
describe "#request_feedback" do
subject { plan.request_feedback(user) }
let!(:org) { create(:org, contact_email: nil) }
let!(:user) { create(:user, org: org) }
let!(:plan) { create(:plan, :creator) }
before do
# Create 2 Org admins for this Org.
create_list(:user, 2, org: org).each do |user|
user.perms << Perm.where(name: 'modify_guidance').first_or_create
end
ActionMailer::Base.deliveries = []
end
it "changes plan's feedback_requested value to true" do
expect { subject }.to change {
plan.reload.feedback_requested
}.from(false).to(true)
end
it "doesn't send any emails" do
expect { subject }.not_to change { ActionMailer::Base.deliveries.size }
end
context "when org contact_email present" do
before do
org.update!(contact_email: Faker::Internet.safe_email)
end
it "emails the admins" do
expect { subject }.to change {
ActionMailer::Base.deliveries.size
}.by(1)
end
end
end
describe "#complete_feedback" do
subject { plan.complete_feedback(user) }
let!(:org) { create(:org) }
let!(:user) { create(:user, org: org) }
let!(:admin) { create(:user) }
let!(:template) { create(:template, phases: 2) }
let!(:plan) { create(:plan, feedback_requested: true,
template: template) }
before do
create(:role, :creator, plan: plan, user: user)
# This person gets the email notification
create(:role, :administrator, plan: plan, user: admin)
end
it "changes plan's feedback_requested value to false" do
expect { subject }.to change {
plan.reload.feedback_requested
}.from(true).to(false)
end
it "doesn't send any emails" do
User.any_instance.stubs(:get_preferences)
.returns(:users => { :feedback_provided => false })
expect { subject }.not_to change { ActionMailer::Base.deliveries.size }
end
context "when user feedback provided pref is true" do
before do
User.any_instance.stubs(:get_preferences)
.returns(:users => { :feedback_provided => true })
end
it "emails the owners" do
expect { subject }.to change {
ActionMailer::Base.deliveries.size
}.by(2)
end
end
end
describe "#guidance_by_question_as_hash" do
end
describe "#editable_by?" do
let!(:plan) { build_plan(true, true, true) }
subject { plan }
it "when role is inactive" do
role = subject.roles.editor.first
role.deactivate!
user = role.user
expect(subject.editable_by?(user.id)).to eql(false)
end
it "when user is a creator" do
# All creators should be able to edit
subject.roles.creator.pluck(:user_id).each do |user_id|
expect(subject.editable_by?(user_id)).to eql(true)
end
end
it "when user is a administrator" do
# All administrators (aka coowners) should be able to edit
subject.roles.administrator.pluck(:user_id).each do |user_id|
expect(subject.editable_by?(user_id)).to eql(true)
end
end
it "when user is a editor" do
# All editors should be able to edit
subject.roles.editor.pluck(:user_id).each do |user_id|
expect(subject.editable_by?(user_id)).to eql(true)
end
end
it "when user is a commenter" do
# Commenters should only be able to edit if they are also
# a creator, administrator or editor
subject.roles.commenter.each do |role|
expect(subject.editable_by?(role.user.id)).to eql(role.editor?)
end
end
end
describe "#readable_by?" do
let!(:user) { create(:user, org: create(:org)) }
let!(:plan) { build_plan(true, true, true) }
subject { plan }
context "config allows for admin viewing" do
it "super admins" do
Branding.expects(:fetch)
.with(:service_configuration, :plans, :super_admins_read_all)
.returns(true)
user.perms << create(:perm, name: "add_organisations")
expect(subject.readable_by?(user.id)).to eql(true)
end
it "org admins" do
Branding.expects(:fetch)
.with(:service_configuration, :plans, :org_admins_read_all)
.returns(true)
user.org_id = plan.owner.org_id
user.save
user.perms << create(:perm, name: "modify_guidance")
expect(subject.readable_by?(user.id)).to eql(true)
end
end
context "config does not allow admin viewing" do
it "super admins" do
Branding.expects(:fetch)
.with(:service_configuration, :plans, :super_admins_read_all)
.returns(false)
user.perms << create(:perm, name: "add_organisations")
expect(subject.readable_by?(user.id)).to eql(false)
end
it "org admins" do
Branding.expects(:fetch)
.with(:service_configuration, :plans, :org_admins_read_all)
.returns(false)
user.perms << create(:perm, name: "modify_guidance")
expect(subject.readable_by?(user.id)).to eql(false)
end
end
context "non-admin user" do
it "when role is inactive" do
role = subject.roles.commenter.first
role.deactivate!
user = role.user
expect(subject.readable_by?(user.id)).to eql(false)
end
it "when user is a creator" do
# All creators should be able to read
subject.roles.creator.pluck(:user_id).each do |user_id|
expect(subject.readable_by?(user_id)).to eql(true)
end
end
it "when user is a administrator" do
# All administrators should be able to read
subject.roles.administrator.pluck(:user_id).each do |user_id|
expect(subject.readable_by?(user_id)).to eql(true)
end
end
it "when user is a editor" do
# All editors should be able to read
subject.roles.editor.pluck(:user_id).each do |user_id|
expect(subject.readable_by?(user_id)).to eql(true)
end
end
it "when user is a commenter" do
# All commenters should be able to read
subject.roles.commenter.pluck(:user_id).each do |user_id|
expect(subject.readable_by?(user_id)).to eql(true)
end
end
context "When user is a reviewer" do
before do
user.org = plan.owner.org
user.save
user.perms << create(:perm, :review_org_plans)
end
it "when user is a reviewer and feedback requested" do
# All reviewers of the same org should be able to comment
plan.feedback_requested = true
plan.save
expect(subject.readable_by?(user.id)).to eql(true)
end
it "when user is a reviewer and feedback not requested" do
Branding.expects(:fetch)
.with(:service_configuration, :plans, :org_admins_read_all)
.returns(false)
plan.feedback_requested = false
plan.save
expect(subject.readable_by?(user.id)).to eql(false)
end
it "when user is a reviewer of a different org and feedback requested" do
# reviewers of other orgs should have no access
user.org = create(:org)
user.save
user.perms << create(:perm, :review_org_plans)
plan.feedback_requested = true
plan.save
expect(subject.readable_by?(user.id)).to eql(false)
end
end
it "when user is not reviewer, has no roles on the plan and feedback requested" do
# All reviewers should be able to comment
user.org = plan.owner.org
user.save
plan.feedback_requested = true
plan.save
expect(subject.readable_by?(user.id)).to eql(false)
end
end
end
describe "#commentable_by?" do
let!(:plan) { build_plan(true, true, true) }
subject { plan }
it "when role is inactive" do
role = subject.roles.commenter.first
role.deactivate!
user = role.user
expect(subject.commentable_by?(user.id)).to eql(false)
end
it "when user is a creator" do
# All creators should be able to comment
subject.roles.creator.pluck(:user_id).each do |user_id|
expect(subject.commentable_by?(user_id)).to eql(true)
end
end
it "when user is a administrator" do
# All administrators should be able to comment
subject.roles.administrator.pluck(:user_id).each do |user_id|
expect(subject.commentable_by?(user_id)).to eql(true)
end
end
it "when user is a editor" do
# All editors should be able to comment
subject.roles.editor.pluck(:user_id).each do |user_id|
expect(subject.commentable_by?(user_id)).to eql(true)
end
end
it "when user is a commenter" do
# All commenters should be able to comment
subject.roles.commenter.pluck(:user_id).each do |user_id|
expect(subject.commentable_by?(user_id)).to eql(true)
end
end
let(:user) { create(:user) }
context "when user is a reviewer" do
before do
user.org = plan.owner.org
user.save
user.perms << create(:perm, :review_org_plans)
end
it "of the same org and feedback requested" do
# All reviewers of the same org should be able to comment
plan.feedback_requested = true
plan.save
expect(subject.commentable_by?(user.id)).to eql(true)
end
it "of the same org and feedback not requested" do
plan.feedback_requested = false
plan.save
expect(subject.commentable_by?(user.id)).to eql(false)
end
it "of a different org and feedback requested" do
# All reviewers of other orgs should not be able to comment
user.org = create(:org)
user.save
# re-add permissions as org-admins will have these removed on save
user.perms << create(:perm, :review_org_plans)
plan.feedback_requested = true
plan.save
expect(subject.commentable_by?(user.id)).to eql(false)
end
end
it "when user is not reviewer, has no roles on the plan and feedback requested" do
# All reviewers should be able to comment
user.org = plan.owner.org
user.save
plan.feedback_requested = true
plan.save
expect(subject.commentable_by?(user.id)).to eql(false)
end
end
describe "#administerable_by?" do
let!(:plan) { build_plan(true, true, true) }
subject { plan }
it "when role is inactive" do
role = subject.roles.administrator.first
role.deactivate!
user = role.user
expect(subject.administerable_by?(user.id)).to eql(false)
end
it "when user is a creator" do
# All creators should be able to administer
subject.roles.creator.pluck(:user_id).each do |user_id|
expect(subject.administerable_by?(user_id)).to eql(true)
end
end
it "when user is a administrator" do
# All administrators should be able to administer
subject.roles.administrator.pluck(:user_id).each do |user_id|
expect(subject.administerable_by?(user_id)).to eql(true)
end
end
it "when user is a editor" do
# Editors should only be able to administer if they are also
# a creator or administrator
subject.roles.editor.each do |role|
expect(subject.administerable_by?(role.user.id)).to eql(role.administrator?)
end
end
it "when user is a commenter" do
# Commenters should only be able to administer if they are also
# a creator or administrator
subject.roles.commenter.each do |role|
expect(subject.administerable_by?(role.user.id)).to eql(role.administrator?)
end
end
end
describe "#reviewable_by?" do
let!(:plan) { build_plan(true, true, true) }
let!(:user) { create(:user) }
before do
plan.feedback_requested = true
plan.save
create(:perm, :review_org_plans)
end
subject { plan }
it "when user is not a reviewer" do
expect(subject.reviewable_by?(user.id)).to eql(false)
end
it "when user is a reviewer" do
user.org = plan.owner.org
user.save
user.perms << Perm.review_plans
expect(subject.owner.org).to eql(user.org)
expect(user.can_review_plans?).to eql(true)
expect(plan.feedback_requested?).to eql(true)
expect(subject.reviewable_by?(user.id)).to eql(true)
end
end
describe "#latest_update" do
let!(:plan) { create(:plan, :creator, updated_at: 5.minutes.ago) }
subject { plan.latest_update.to_i }
context "when plan updated_at is latest" do
before do
create_list(:phase, 2, template: plan.template,
updated_at: 6.minutes.ago)
end
it "returns the plan's updated_at value" do
is_expected.to be_within(5.seconds).of(5.minutes.ago.to_i)
end
end
context "when plan has phases updated_at latest" do
before do
create_list(:phase, 2, template: plan.template)
end
it "returns the plan's updated_at value" do
is_expected.to be_within(5.seconds).of(Time.current.to_i)
end
end
end
describe "#name" do
let!(:plan) { build(:plan, :creator, title: "Foo bar") }
it "returns the title" do
expect(plan.name).to eql("Foo bar")
end
end
describe "#owner" do
let!(:plan) { build_plan(true, true, true) }
subject { plan }
it "is the creator" do
user = subject.roles.creator.first.user
expect(subject.owner).to eql(user)
end
it "is the administrator if there is no creator" do
subject.roles.creator.first.deactivate!
user = subject.roles.where(active: true).administrator.first.user
expect(subject.owner).to eql(user)
end
end
describe "#add_user" do
let!(:user) { create(:user, org: create(:org)) }
let!(:plan) { build_plan }
subject { plan }
it "returns false if user does not exist" do
expect(subject.add_user!(326465)).to eql(false)
end
it "adds the creator" do
expect(subject.add_user!(user.id, :creator)).to eql(true)
role = Role.find_by(user_id: user.id, plan_id: subject.id)
expect(role.creator?).to eql(true)
expect(role.administrator?).to eql(true)
expect(role.editor?).to eql(true)
expect(role.commenter?).to eql(true)
expect(role.reviewer?).to eql(false)
end
it "adds the administrator" do
expect(subject.add_user!(user.id, :administrator)).to eql(true)
role = Role.find_by(user_id: user.id, plan_id: subject.id)
expect(role.creator?).to eql(false)
expect(role.administrator?).to eql(true)
expect(role.editor?).to eql(true)
expect(role.commenter?).to eql(true)
expect(role.reviewer?).to eql(false)
end
it "adds the editor" do
expect(subject.add_user!(user.id, :editor)).to eql(true)
role = Role.find_by(user_id: user.id, plan_id: subject.id)
expect(role.creator?).to eql(false)
expect(role.administrator?).to eql(false)
expect(role.editor?).to eql(true)
expect(role.commenter?).to eql(true)
expect(role.reviewer?).to eql(false)
end
it "adds the commenter" do
expect(subject.add_user!(user.id, :commenter)).to eql(true)
role = Role.find_by(user_id: user.id, plan_id: subject.id)
expect(role.creator?).to eql(false)
expect(role.administrator?).to eql(false)
expect(role.editor?).to eql(false)
expect(role.commenter?).to eql(true)
expect(role.reviewer?).to eql(false)
end
it "defaults to commenter if access_level is not a known symbol" do
expect(subject.add_user!(user.id)).to eql(true)
role = Role.find_by(user_id: user.id, plan_id: subject.id)
expect(role.creator?).to eql(false)
expect(role.administrator?).to eql(false)
expect(role.editor?).to eql(false)
expect(role.commenter?).to eql(true)
expect(role.reviewer?).to eql(false)
end
end
describe "#shared?" do
it "is not shared if the only user is the creator" do
plan = build_plan
expect(plan.shared?).to eql(false)
end
it "is shared if the plan has an administrator" do
plan = build_plan(true, false, false)
expect(plan.shared?).to eql(true)
end
it "is shared if the plan has an editor" do
plan = build_plan(false, true, false)
expect(plan.shared?).to eql(true)
end
it "is shared if the plan has an commenter" do
plan = build_plan(false, false, true)
expect(plan.shared?).to eql(true)
end
end
describe "#owner_and_coowners" do
let!(:plan) { build_plan(true, true, true) }
subject { plan }
it "includes the creator" do
user = subject.roles.creator.first.user
expect(subject.owner_and_coowners).to include(user)
end
it "includes the administrator" do
user = subject.roles.administrator.first.user
expect(subject.owner_and_coowners).to include(user)
end
it "does not include the editor" do
# Only if the editor is not also an administrator or creator
subject.roles.editor.each do |role|
if !role.creator? && !role.administrator?
expect(subject.owner_and_coowners).to_not include(role.user)
end
end
end
it "does not include the commenter" do
# Only if the commenter is not also an administrator or creator
subject.roles.commenter.each do |role|
if !role.creator? && !role.administrator?
expect(subject.owner_and_coowners).to_not include(role.user)
end
end
end
end
describe ".authors" do
let!(:plan) { build_plan(true, true, true) }
subject { plan }
it "includes the creator" do
user = subject.roles.creator.first.user
expect(subject.authors).to include(user)
end
it "includes the administrator" do
user = subject.roles.administrator.first.user
expect(subject.authors).to include(user)
end
it "includes the editor" do
user = subject.roles.editor.first.user
expect(subject.authors).to include(user)
end
it "does not include the commenter" do
# Only if the commenter is not also an editor, administrator or creator
subject.roles.commenter.each do |role|
if !role.creator? && !role.administrator? && !role.editor?
expect(subject.authors).to_not include(role.user)
end
end
end
end
describe "#num_answered_questions" do
let!(:template) { create(:template) }
let!(:plan) { create(:plan, :creator, template: template) }
subject { plan.num_answered_questions }
before do
@phase = create(:phase, template: template)
@section = create(:section, phase: @phase)
@questions = create_list(:question, 3, :textarea, section: @section)
# 2 valid answers
@questions.first(2).each do |question|
create(:answer, question: question, plan: plan)
end
# 1 valid answers
@questions.last(1).each do |question|
create(:answer, question: question, plan: plan, text: nil)
end
end
it "returns the number of questions with valid answers" do
expect(subject).to eql(2)
end
end
describe "#num_questions" do
let!(:template) { create(:template) }
let!(:plan) { create(:plan, :creator, template: template) }
subject { plan.num_questions }
before do
create_list(:phase, 2, template: template) do |phase|
create_list(:section, 2, phase: phase) do |section|
create_list(:question, 3, section: section)
end
end
end
it "returns the number of questions belonging to this plan's sections" do
expect(subject).to eql(12)
end
end
describe "#visibility_allowed?" do
let!(:template) { create(:template) }
let!(:plan) { create(:plan, :creator, template: template) }
subject { plan.visibility_allowed? }
before do
@phase = create(:phase, template: template)
@section = create(:section, phase: @phase)
@questions = create_list(:question, 4, :textarea, section: @section)
@questions.take(3).each do |question|
create(:answer, question: question, plan: plan)
end
end
context "when requisite number of questions answered" do
before do
Rails.application.config.default_plan_percentage_answered = 75
end
it { is_expected.to eql(true) }
end
context "when requisite number of questions not answered" do
before do
Rails.application.config.default_plan_percentage_answered = 76
end
it { is_expected.to eql(false) }
end
end
describe "#question_exists?" do
context "when Question with ID and Plan exists" do
let!(:question) { create(:question) }
let!(:plan) { create(:plan, :creator, template: question.section.phase.template) }
subject { plan.question_exists?(question.id) }
it { is_expected.to eql(true) }
end
context "when Question with ID and Plan don't exist" do
let!(:question) { create(:question) }
let!(:plan) { create(:plan, :creator) }
subject { plan.question_exists?(question.id) }
it { is_expected.to eql(false) }
end
end
describe "#no_questions_matches_no_answers?" do
let!(:plan) { create(:plan, :creator) }
subject { plan.no_questions_matches_no_answers? }
context "when has no answers" do
it { is_expected.to eql(true) }
end
context "when has answers that are not valid" do
let!(:question) { create(:question, :textarea) }
before do
create_list(:answer, 1, text: "", plan: plan, question: question)
end
it { is_expected.to eql(true) }
end
context "when has answers that are valid" do
let!(:question) { create(:question, :textarea) }
before do
create_list(:answer, 1, plan: plan, question: question)
end
it { is_expected.to eql(false) }
end
end
end