Skip to content
Snippets Groups Projects
Commit 6f5e383a authored by zhanglinjie's avatar zhanglinjie
Browse files

Add content_blocked_state model

parent 081c311c
No related merge requests found
# frozen_string_literal: true
module ContentValidation
class ContentBlockedState < ApplicationRecord
self.table_name = 'content_blocked_states'
include Gitlab::Utils::StrongMemoize
include ShaAttribute
validates :container_identifier, presence: true
validates :commit_sha, presence: true
validates :blob_sha, presence: true
validates :path, presence: true
sha_attribute :commit_sha
sha_attribute :blob_sha
delegate :full_path, to: :project, prefix: true, allow_nil: true
def identifier
strong_memoize(:identifier) { ::Gitlab::GlRepository::Identifier.parse(container_identifier) }
end
def container
strong_memoize(:container) { identifier.container }
end
def repo_type
strong_memoize(:repo_type) { identifier.repo_type }
end
def project
strong_memoize(:project) { repo_type.project_for(container) }
end
def self.blocked?(container_identifier:, commit_sha:, path:)
where(container_identifier: container_identifier, commit_sha: commit_sha, path: path).exists?
end
def self.find_container_commit_path(container, commit_sha, path)
container_identifier = container.repository.repo_type.identifier_for_container(container)
where(container_identifier: container_identifier, commit_sha: commit_sha, path: path).first
end
def self.find_wiki_page(page)
container_identifier = page.wiki.repository.repo_type.identifier_for_container(page.wiki)
commit = page.version.commit
where(container_identifier: container_identifier, commit_sha: commit.id, path: page.path).first
end
def self.find_snippet_path(snippet, path)
last_commit = Gitlab::Git::Commit.last_for_path(snippet.repository, snippet.default_branch, path)
container_identifier = snippet.repository.repo_type.identifier_for_container(snippet)
where(container_identifier: container_identifier, commit_sha: last_commit&.id, path: path).first
end
def self.find_snippet_paths(snippet)
snippet.list_files.map { |file| find_snippet_path(snippet, file) }.compact
end
end
end
# frozen_string_literal: true
FactoryBot.define do
factory :content_blocked_state, class: 'ContentValidation::ContentBlockedState' do
commit_sha { RepoHelpers.sample_commit.id }
blob_sha { RepoHelpers.sample_blob.oid }
path { RepoHelpers.sample_blob.path }
container_identifier { "project-xxx" }
transient do
container { nil }
end
after(:build) do |content_blocked_state, evaluator|
if evaluator.container
repo_type =
if evaluator.container.is_a?(Project)
::Gitlab::GlRepository::PROJECT
elsif evaluator.container.is_a?(Wiki)
::Gitlab::GlRepository::WIKI
elsif evaluator.container.is_a?(Snippet)
::Gitlab::GlRepository::SNIPPET
end
content_blocked_state.container_identifier = repo_type.identifier_for_container(evaluator.container)
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe ContentValidation::ContentBlockedState do
include RepoHelpers
let_it_be(:project) { create(:project, :repository, :repository, :public) }
let_it_be(:wiki) { create(:project_wiki) }
let_it_be(:snippet) { create(:project_snippet, :repository, :public) }
let(:project_content_blocked_state) { create(:content_blocked_state, container: project) }
let(:wiki_content_blocked_state) { create(:content_blocked_state, container: wiki) }
let(:snippet_content_blocked_state) { create(:content_blocked_state, container: snippet) }
describe 'validations' do
it { is_expected.to validate_presence_of(:container_identifier) }
it { is_expected.to validate_presence_of(:commit_sha) }
it { is_expected.to validate_presence_of(:blob_sha) }
it { is_expected.to validate_presence_of(:path) }
end
describe 'delegations' do
it { is_expected.to delegate_method(:full_path).to(:project).with_prefix.allow_nil }
end
describe "#identifier" do
it "return a instance of Gitlab::GlRepository::Identifier" do
expect(project_content_blocked_state.identifier).to be_a(Gitlab::GlRepository::Identifier)
end
end
describe "#container" do
it "return project if container is a project" do
expect(project_content_blocked_state.container).to eq(project)
end
it "return wiki if container is a wiki" do
expect(wiki_content_blocked_state.container).to eq(wiki)
end
it "return snippet if container is a snippet" do
expect(snippet_content_blocked_state.container).to eq(snippet)
end
end
describe "#repo_type" do
it "return PROJECT if container is a project" do
expect(project_content_blocked_state.repo_type).to eq(Gitlab::GlRepository::PROJECT)
end
it "return WIKI if container is a wiki" do
expect(wiki_content_blocked_state.repo_type).to eq(Gitlab::GlRepository::WIKI)
end
it "return SNIPPET if container is a snippet" do
expect(snippet_content_blocked_state.repo_type).to eq(Gitlab::GlRepository::SNIPPET)
end
end
describe "#project" do
it "return project self if container is a project" do
expect(project_content_blocked_state.project).to eq(project)
end
it "return wiki project if container is a wiki" do
expect(wiki_content_blocked_state.project).to eq(wiki.project)
end
it "return snippet project if container is a snippet" do
expect(snippet_content_blocked_state.project).to eq(snippet.project)
end
end
describe "#blocked?" do
it "return true if find content blocked state" do
expect(described_class.blocked?(container_identifier: project_content_blocked_state.container_identifier,
commit_sha: project_content_blocked_state.commit_sha,
path: project_content_blocked_state.path)).to eq(true)
end
it "return false if not find content blocked state" do
expect(described_class.blocked?(container_identifier: "project-none",
commit_sha: "commit-sha-none",
path: "path-none")).to eq(false)
end
end
describe "#find_container_commit_path" do
it "find blocked state by commit_sha and path" do
expect(described_class.find_container_commit_path(project, project_content_blocked_state.commit_sha, project_content_blocked_state.path)).to eq(project_content_blocked_state)
end
end
describe "#find_wiki_page" do
let(:wiki_page) { create(:wiki_page, wiki: wiki) }
let(:content_blocked_state) { create(:content_blocked_state, container: wiki, commit_sha: wiki_page.version.commit.id, path: wiki_page.path) }
it "return wiki page blocked state" do
content_blocked_state
expect(described_class.find_wiki_page(wiki_page)).to eq(content_blocked_state)
end
end
context "snippet" do
let(:commit) { sample_commit }
let(:content_blocked_state) { create(:content_blocked_state, container: snippet, commit_sha: commit.id, path: snippet.file_name) }
before do
allow(Gitlab::Git::Commit).to receive(:last_for_path).and_return(commit)
end
describe "#find_snippet_path" do
it "return snippet path blocked state" do
expect(described_class.find_snippet_path(snippet, content_blocked_state.path)).to eq(content_blocked_state)
end
end
describe "#find_snippet_paths" do
before do
# rubocop:disable RSpec/AnyInstanceOf
allow_any_instance_of(::Snippet).to receive(:list_files).and_return([snippet.file_name])
# rubocop:enable RSpec/AnyInstanceOf
content_blocked_state
end
it "return snippet paths blocked state" do
expect(described_class.find_snippet_paths(snippet)).to eq([content_blocked_state])
end
end
end
end
# frozen_string_literal: true
RSpec.configure do |config|
config.before(:suite) do
FactoryBot.definition_file_paths = [
Rails.root.join('jh', 'spec', 'factories')
]
FactoryBot.find_definitions
end
end
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment