2022-01-01 13:38:12 +00:00
|
|
|
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
|
2021-06-01 12:20:20 +00:00
|
|
|
|
2019-06-04 03:40:48 +00:00
|
|
|
require 'rails_helper'
|
|
|
|
require 'models/concerns/checks_kb_client_notification_examples'
|
|
|
|
require 'models/contexts/factory_context'
|
|
|
|
|
2019-09-18 17:25:04 +00:00
|
|
|
RSpec.describe KnowledgeBase::Category, type: :model, current_user_id: 1 do
|
2019-06-04 03:40:48 +00:00
|
|
|
subject(:kb_category) { create(:knowledge_base_category) }
|
|
|
|
|
|
|
|
include_context 'factory'
|
|
|
|
|
|
|
|
it_behaves_like 'ChecksKbClientNotification'
|
|
|
|
|
|
|
|
it { is_expected.to validate_presence_of(:category_icon) }
|
|
|
|
it { is_expected.not_to validate_presence_of(:parent_id) }
|
|
|
|
|
|
|
|
it { is_expected.to have_many(:answers) }
|
|
|
|
it { is_expected.to have_many(:children) }
|
2022-02-24 11:15:19 +00:00
|
|
|
it { is_expected.to have_many(:permissions) }
|
2019-07-04 11:16:55 +00:00
|
|
|
it { is_expected.to belong_to(:parent).optional }
|
2019-06-04 03:40:48 +00:00
|
|
|
it { is_expected.to belong_to(:knowledge_base) }
|
|
|
|
|
|
|
|
context 'in multilevel tree' do
|
|
|
|
subject(:kb_category_with_tree) { create(:kb_category_with_tree) }
|
|
|
|
|
|
|
|
let(:knowledge_base) { kb_category_with_tree.knowledge_base }
|
|
|
|
let(:child_category) { kb_category_with_tree.children.order(position: :asc).last }
|
|
|
|
let(:grandchild_category) { child_category.children.order(position: :asc).first }
|
|
|
|
|
|
|
|
it 'tests to fetch all categories in KB' do
|
|
|
|
expect(knowledge_base.categories.count).to eq(7)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'fetches root categories' do
|
|
|
|
expect(knowledge_base.categories.root).to contain_exactly(kb_category_with_tree)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'fetches direct children' do
|
|
|
|
expect(kb_category_with_tree.children.count).to eq 2
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'fetches all children' do
|
|
|
|
expect(kb_category_with_tree.self_with_children.count).to eq 7
|
|
|
|
end
|
|
|
|
|
2021-05-31 12:59:49 +00:00
|
|
|
it 'fetches all parents' do
|
|
|
|
expect(grandchild_category.self_with_parents.count).to eq 3
|
|
|
|
end
|
|
|
|
|
2019-06-04 03:40:48 +00:00
|
|
|
it 'root category has no parent' do
|
|
|
|
expect(kb_category_with_tree.parent).to be_blank
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'children category has to have a parent' do
|
|
|
|
expect(child_category.parent).to be_present
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when fetching self with children' do
|
|
|
|
it 'root category has multiple layers children and matches all KB categories' do
|
|
|
|
expect(kb_category_with_tree.self_with_children).to match_array(knowledge_base.categories)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'child category has multiple layers of children' do
|
|
|
|
expect(child_category.self_with_children.count).to eq 5
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'grandchild category has single layer of children' do
|
|
|
|
expect(grandchild_category.self_with_children.count).to eq 3
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when fetchching self with children ids' do
|
|
|
|
it 'root category has multiple layers children ids' do
|
|
|
|
expect(kb_category_with_tree.self_with_children_ids).to match_array(knowledge_base.category_ids)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'child category has with multiple layers of children ids' do
|
|
|
|
expect(child_category.self_with_children_ids.count).to eq 5
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'grandchild category has single layer of children ids count' do
|
|
|
|
expect(grandchild_category.self_with_children_ids.count).to eq 3
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'grandchild category children ids matches direct children ids' do
|
|
|
|
expect(grandchild_category.self_with_children_ids).to match_array([grandchild_category.id] + grandchild_category.child_ids)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when checking if item is a parent of' do
|
|
|
|
it 'root category is indirect (and direct) parent of child' do
|
|
|
|
expect(child_category).to be_self_parent(kb_category_with_tree)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'root category is indirect parent of grandchild' do
|
|
|
|
expect(grandchild_category).to be_self_parent(kb_category_with_tree)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'child category is not a parent of root category' do
|
|
|
|
expect(kb_category_with_tree).not_to be_self_parent(grandchild_category)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2020-08-05 13:48:41 +00:00
|
|
|
|
|
|
|
describe '#public_content?' do
|
|
|
|
shared_examples 'verify visibility in given state' do |state:, is_visible:|
|
|
|
|
it "returns #{is_visible} when contains #{state} answer" do
|
|
|
|
object = create(:knowledge_base_category, "containing_#{state}")
|
|
|
|
|
|
|
|
expect(object).send is_visible ? :to : :not_to, be_public_content(object.translations.first.kb_locale)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
include_examples 'verify visibility in given state', state: :published, is_visible: true
|
|
|
|
include_examples 'verify visibility in given state', state: :internal, is_visible: false
|
|
|
|
include_examples 'verify visibility in given state', state: :draft, is_visible: false
|
|
|
|
include_examples 'verify visibility in given state', state: :archived, is_visible: false
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#internal_content?' do
|
|
|
|
shared_examples 'verify visibility in given state' do |state:, is_visible:|
|
|
|
|
it "returns #{is_visible} when contains #{state} answer" do
|
|
|
|
object = create(:knowledge_base_category, "containing_#{state}")
|
|
|
|
|
|
|
|
expect(object).send is_visible ? :to : :not_to, be_internal_content(object.translations.first.kb_locale)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
include_examples 'verify visibility in given state', state: :published, is_visible: true
|
|
|
|
include_examples 'verify visibility in given state', state: :internal, is_visible: true
|
|
|
|
include_examples 'verify visibility in given state', state: :draft, is_visible: false
|
|
|
|
include_examples 'verify visibility in given state', state: :archived, is_visible: false
|
|
|
|
end
|
2022-02-25 22:46:10 +00:00
|
|
|
|
|
|
|
describe '#assets', current_user_id: -> { user.id } do
|
|
|
|
subject(:assets) { another_category_answer && internal_answer && category.assets }
|
|
|
|
|
|
|
|
include_context 'basic Knowledge Base'
|
|
|
|
|
|
|
|
let(:user) { create(:agent) }
|
|
|
|
let(:another_category) { create(:knowledge_base_category, knowledge_base: knowledge_base) }
|
|
|
|
let(:another_category_answer) { create(:knowledge_base_answer, :internal, category: another_category) }
|
|
|
|
|
|
|
|
context 'without permissions' do
|
|
|
|
it { expect(assets).to include_assets_of category }
|
|
|
|
it { expect(assets).to include_assets_of another_category }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with readable another category' do
|
|
|
|
before do
|
|
|
|
KnowledgeBase::PermissionsUpdate
|
|
|
|
.new(another_category)
|
|
|
|
.update! user.roles.first => 'reader'
|
|
|
|
end
|
|
|
|
|
|
|
|
it { expect(assets).to include_assets_of category }
|
|
|
|
it { expect(assets).to include_assets_of another_category }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with hidden another category' do
|
|
|
|
before do
|
|
|
|
KnowledgeBase::PermissionsUpdate
|
|
|
|
.new(another_category)
|
|
|
|
.update! user.roles.first => 'none'
|
|
|
|
end
|
|
|
|
|
|
|
|
it { expect(assets).to include_assets_of category }
|
|
|
|
it { expect(assets).not_to include_assets_of another_category }
|
|
|
|
|
|
|
|
context 'with published answer' do
|
|
|
|
let(:another_category_published_answer) { create(:knowledge_base_answer, :published, category: another_category) }
|
|
|
|
|
|
|
|
before { another_category_published_answer }
|
|
|
|
|
|
|
|
it { expect(assets).to include_assets_of category }
|
|
|
|
it { expect(assets).to include_assets_of another_category }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2019-06-04 03:40:48 +00:00
|
|
|
end
|