require 'spec_helper' describe Note, ResolvableNote, models: true do let(:project) { create(:project) } let(:merge_request) { create(:merge_request, source_project: project) } subject { create(:discussion_note_on_merge_request, noteable: merge_request, project: project) } context 'resolvability scopes' do let!(:note1) { create(:note, project: project) } let!(:note2) { create(:diff_note_on_commit, project: project) } let!(:note3) { create(:diff_note_on_merge_request, :resolved, noteable: merge_request, project: project) } let!(:note4) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project) } let!(:note5) { create(:discussion_note_on_issue, project: project) } let!(:note6) { create(:discussion_note_on_merge_request, :system, noteable: merge_request, project: project) } describe '.potentially_resolvable' do it 'includes diff and discussion notes on merge requests' do expect(Note.potentially_resolvable).to match_array([note3, note4, note6]) end end describe '.resolvable' do it 'includes non-system diff and discussion notes on merge requests' do expect(Note.resolvable).to match_array([note3, note4]) end end describe '.resolved' do it 'includes resolved non-system diff and discussion notes on merge requests' do expect(Note.resolved).to match_array([note3]) end end describe '.unresolved' do it 'includes non-resolved non-system diff and discussion notes on merge requests' do expect(Note.unresolved).to match_array([note4]) end end end describe ".resolve!" do let(:current_user) { create(:user) } let!(:commit_note) { create(:diff_note_on_commit, project: project) } let!(:resolved_note) { create(:discussion_note_on_merge_request, :resolved, noteable: merge_request, project: project) } let!(:unresolved_note) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project) } before do described_class.resolve!(current_user) commit_note.reload resolved_note.reload unresolved_note.reload end it 'resolves only the resolvable, not yet resolved notes' do expect(commit_note.resolved_at).to be_nil expect(resolved_note.resolved_by).not_to eq(current_user) expect(unresolved_note.resolved_at).not_to be_nil expect(unresolved_note.resolved_by).to eq(current_user) end end describe ".unresolve!" do let!(:resolved_note) { create(:discussion_note_on_merge_request, :resolved, noteable: merge_request, project: project) } before do described_class.unresolve! resolved_note.reload end it 'unresolves the resolved notes' do expect(resolved_note.resolved_by).to be_nil expect(resolved_note.resolved_at).to be_nil end end describe '#resolvable?' do context "when potentially resolvable" do before do allow(subject).to receive(:potentially_resolvable?).and_return(true) end context "when a system note" do before do subject.system = true end it "returns false" do expect(subject.resolvable?).to be false end end context "when a regular note" do it "returns true" do expect(subject.resolvable?).to be true end end end context "when not potentially resolvable" do before do allow(subject).to receive(:potentially_resolvable?).and_return(false) end it "returns false" do expect(subject.resolvable?).to be false end end end describe "#to_be_resolved?" do context "when not resolvable" do before do allow(subject).to receive(:resolvable?).and_return(false) end it "returns false" do expect(subject.to_be_resolved?).to be false end end context "when resolvable" do before do allow(subject).to receive(:resolvable?).and_return(true) end context "when resolved" do before do allow(subject).to receive(:resolved?).and_return(true) end it "returns false" do expect(subject.to_be_resolved?).to be false end end context "when not resolved" do before do allow(subject).to receive(:resolved?).and_return(false) end it "returns true" do expect(subject.to_be_resolved?).to be true end end end end describe "#resolved?" do let(:current_user) { create(:user) } context 'when not resolvable' do before do subject.resolve!(current_user) allow(subject).to receive(:resolvable?).and_return(false) end it 'returns false' do expect(subject.resolved?).to be_falsey end end context 'when resolvable' do context 'when the note has been resolved' do before do subject.resolve!(current_user) end it 'returns true' do expect(subject.resolved?).to be_truthy end end context 'when the note has not been resolved' do it 'returns false' do expect(subject.resolved?).to be_falsey end end end end describe "#resolve!" do let(:current_user) { create(:user) } context "when not resolvable" do before do allow(subject).to receive(:resolvable?).and_return(false) end it "returns nil" do expect(subject.resolve!(current_user)).to be_nil end it "doesn't set resolved_at" do subject.resolve!(current_user) expect(subject.resolved_at).to be_nil end it "doesn't set resolved_by" do subject.resolve!(current_user) expect(subject.resolved_by).to be_nil end it "doesn't mark as resolved" do subject.resolve!(current_user) expect(subject.resolved?).to be false end end context "when resolvable" do before do allow(subject).to receive(:resolvable?).and_return(true) end context "when already resolved" do let(:user) { create(:user) } before do subject.resolve!(user) end it "returns nil" do expect(subject.resolve!(current_user)).to be_nil end it "doesn't change resolved_at" do expect(subject.resolved_at).not_to be_nil expect { subject.resolve!(current_user) }.not_to change { subject.resolved_at } end it "doesn't change resolved_by" do expect(subject.resolved_by).to eq(user) expect { subject.resolve!(current_user) }.not_to change { subject.resolved_by } end it "doesn't change resolved status" do expect(subject.resolved?).to be true expect { subject.resolve!(current_user) }.not_to change { subject.resolved? } end end context "when not yet resolved" do it "returns true" do expect(subject.resolve!(current_user)).to be true end it "sets resolved_at" do subject.resolve!(current_user) expect(subject.resolved_at).not_to be_nil end it "sets resolved_by" do subject.resolve!(current_user) expect(subject.resolved_by).to eq(current_user) end it "marks as resolved" do subject.resolve!(current_user) expect(subject.resolved?).to be true end end end end describe "#unresolve!" do context "when not resolvable" do before do allow(subject).to receive(:resolvable?).and_return(false) end it "returns nil" do expect(subject.unresolve!).to be_nil end end context "when resolvable" do before do allow(subject).to receive(:resolvable?).and_return(true) end context "when resolved" do let(:user) { create(:user) } before do subject.resolve!(user) end it "returns true" do expect(subject.unresolve!).to be true end it "unsets resolved_at" do subject.unresolve! expect(subject.resolved_at).to be_nil end it "unsets resolved_by" do subject.unresolve! expect(subject.resolved_by).to be_nil end it "unmarks as resolved" do subject.unresolve! expect(subject.resolved?).to be false end end context "when not resolved" do it "returns nil" do expect(subject.unresolve!).to be_nil end end end end end