Commit 40b52543 authored by Vladimir Shushlin's avatar Vladimir Shushlin

Move release evidence generation to service

* Add service for creating release evidence
* Remove spec duplicating release name fallback to tag
* Remove test testing default=nil behaviour
* It maybe made sense if evidence was generated on the fly
* Now it's just testing that default value in ActiveRecord is nil
* Remove evidence generation from the model and move specs
* Use service in the worker instead of calling model
parent 04d6297d
......@@ -6,8 +6,6 @@ class Releases::Evidence < ApplicationRecord
belongs_to :release, inverse_of: :evidences
before_validation :generate_summary_and_sha
default_scope { order(created_at: :asc) }
sha_attribute :summary_sha
......@@ -31,14 +29,4 @@ class Releases::Evidence < ApplicationRecord
safe_summary
end
private
def generate_summary_and_sha
summary = Evidences::EvidenceSerializer.new.represent(self) # rubocop: disable CodeReuse/Serializer
return unless summary
self.summary = summary
self.summary_sha = Gitlab::CryptoHelper.sha256(summary)
end
end
# frozen_string_literal: true
module Releases
class CreateEvidenceService
def initialize(release)
@release = release
end
def execute
evidence = release.evidences.build
summary = Evidences::EvidenceSerializer.new.represent(evidence) # rubocop: disable CodeReuse/Serializer
evidence.summary = summary
# TODO: fix the sha generating https://gitlab.com/gitlab-org/gitlab/-/issues/209000
evidence.summary_sha = Gitlab::CryptoHelper.sha256(summary)
evidence.save!
end
private
attr_reader :release
end
end
......@@ -10,6 +10,6 @@ class CreateEvidenceWorker # rubocop:disable Scalability/IdempotentWorker
release = Release.find_by_id(release_id)
return unless release
Releases::Evidence.create!(release: release)
::Releases::CreateEvidenceService.new(release).execute
end
end
......@@ -87,11 +87,7 @@ describe Projects::Releases::EvidencesController do
let_it_be(:project) { create(:project, :repository, :public) }
let_it_be(:issue) { create(:issue, project: project) }
let_it_be(:milestone) { create(:milestone, project: project, issues: [issue]) }
let_it_be(:release) { create(:release, project: project, tag: tag_name, milestones: [milestone]) }
before do
create(:evidence, release: release)
end
let_it_be(:release) { create(:release, :with_evidence, project: project, tag: tag_name, milestones: [milestone]) }
shared_examples_for 'does not show the issue in evidence' do
it do
......
......@@ -17,7 +17,7 @@ FactoryBot.define do
trait :with_evidence do
after(:create) do |release, _|
create(:evidence, release: release)
::Releases::CreateEvidenceService.new(release).execute
end
end
......
......@@ -3,85 +3,10 @@
require 'spec_helper'
describe Releases::Evidence do
let_it_be(:project) { create(:project) }
let(:release) { create(:release, project: project) }
let(:schema_file) { 'evidences/evidence' }
let(:release) { create(:release) }
let(:summary_json) { described_class.last.summary.to_json }
describe 'associations' do
it { is_expected.to belong_to(:release) }
end
describe 'summary_sha' do
it 'returns nil if summary is nil' do
expect(build(:evidence, summary: nil).summary_sha).to be_nil
end
end
describe '#generate_summary_and_sha' do
before do
described_class.create!(release: release)
end
context 'when a release name is not provided' do
let(:release) { create(:release, project: project, name: nil) }
it 'creates a valid JSON object' do
expect(release.name).to eq(release.tag)
expect(summary_json).to match_schema(schema_file)
end
end
context 'when a release is associated to a milestone' do
let(:milestone) { create(:milestone, project: project) }
let(:release) { create(:release, project: project, milestones: [milestone]) }
context 'when a milestone has no issue associated with it' do
it 'creates a valid JSON object' do
expect(milestone.issues).to be_empty
expect(summary_json).to match_schema(schema_file)
end
end
context 'when a milestone has no description' do
let(:milestone) { create(:milestone, project: project, description: nil) }
it 'creates a valid JSON object' do
expect(milestone.description).to be_nil
expect(summary_json).to match_schema(schema_file)
end
end
context 'when a milestone has no due_date' do
let(:milestone) { create(:milestone, project: project, due_date: nil) }
it 'creates a valid JSON object' do
expect(milestone.due_date).to be_nil
expect(summary_json).to match_schema(schema_file)
end
end
context 'when a milestone has an issue' do
context 'when the issue has no description' do
let(:issue) { create(:issue, project: project, description: nil, state: 'closed') }
before do
milestone.issues << issue
end
it 'creates a valid JSON object' do
expect(milestone.issues.first.description).to be_nil
expect(summary_json).to match_schema(schema_file)
end
end
end
end
context 'when a release is not associated to any milestone' do
it 'creates a valid JSON object' do
expect(release.milestones).to be_empty
expect(summary_json).to match_schema(schema_file)
end
end
end
end
......@@ -3,12 +3,67 @@
require 'spec_helper'
describe Evidences::EvidenceEntity do
let_it_be(:project) { create(:project) }
let(:release) { create(:release, project: project) }
let(:evidence) { build(:evidence) }
let(:entity) { described_class.new(evidence) }
let(:schema_file) { 'evidences/evidence' }
subject { entity.as_json }
it 'exposes the expected fields' do
expect(subject.keys).to contain_exactly(:release)
end
context 'when a release is associated to a milestone' do
let(:milestone) { create(:milestone, project: project) }
let(:release) { create(:release, project: project, milestones: [milestone]) }
context 'when a milestone has no issue associated with it' do
it 'creates a valid JSON object' do
expect(milestone.issues).to be_empty
expect(subject.to_json).to match_schema(schema_file)
end
end
context 'when a milestone has no description' do
let(:milestone) { create(:milestone, project: project, description: nil) }
it 'creates a valid JSON object' do
expect(milestone.description).to be_nil
expect(subject.to_json).to match_schema(schema_file)
end
end
context 'when a milestone has no due_date' do
let(:milestone) { create(:milestone, project: project, due_date: nil) }
it 'creates a valid JSON object' do
expect(milestone.due_date).to be_nil
expect(subject.to_json).to match_schema(schema_file)
end
end
context 'when a milestone has an issue' do
context 'when the issue has no description' do
let(:issue) { create(:issue, project: project, description: nil, state: 'closed') }
before do
milestone.issues << issue
end
it 'creates a valid JSON object' do
expect(milestone.issues.first.description).to be_nil
expect(subject.to_json).to match_schema(schema_file)
end
end
end
end
context 'when a release is not associated to any milestone' do
it 'creates a valid JSON object' do
expect(release.milestones).to be_empty
expect(subject.to_json).to match_schema(schema_file)
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Releases::CreateEvidenceService do
let_it_be(:project) { create(:project) }
let(:release) { create(:release, project: project) }
let(:service) { described_class.new(release) }
it 'creates evidence' do
expect { service.execute }.to change { release.reload.evidences.count }.by(1)
end
it 'saves evidence summary' do
service.execute
evidence = Releases::Evidence.last
expect(release.tag).not_to be_nil
expect(evidence.summary["release"]["tag_name"]).to eq(release.tag)
end
it 'saves sha' do
service.execute
evidence = Releases::Evidence.last
expect(evidence.summary_sha).not_to be_nil
end
end
......@@ -3,9 +3,13 @@
require 'spec_helper'
describe CreateEvidenceWorker do
let!(:release) { create(:release) }
let(:release) { create(:release) }
it 'creates a new Evidence record' do
expect_next_instance_of(::Releases::CreateEvidenceService, release) do |service|
expect(service).to receive(:execute).and_call_original
end
expect { described_class.new.perform(release.id) }.to change(Releases::Evidence, :count).by(1)
end
end
Markdown is supported
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