Commit 2c8b830f authored by Katarzyna Kobierska's avatar Katarzyna Kobierska

Code refactoring

parent bbba62fa
...@@ -7,13 +7,10 @@ module Ci ...@@ -7,13 +7,10 @@ module Ci
def create def create
@content = params[:content] @content = params[:content]
@error = Ci::GitlabCiYamlProcessor.validation_message(@content)
if @content.blank? unless @error.blank?
@status = false @status = @error.blank?
@error = "Please provide content of .gitlab-ci.yml"
elsif !Ci::GitlabCiYamlProcessor.errors(@content).nil?
@status = false
@error = Ci::GitlabCiYamlProcessor.errors(@content)
else else
@config_processor = Ci::GitlabCiYamlProcessor.new(@content) @config_processor = Ci::GitlabCiYamlProcessor.new(@content)
@stages = @config_processor.stages @stages = @config_processor.stages
......
...@@ -81,9 +81,6 @@ Rails.application.routes.draw do ...@@ -81,9 +81,6 @@ Rails.application.routes.draw do
mount Sidekiq::Web, at: '/admin/sidekiq', as: :sidekiq mount Sidekiq::Web, at: '/admin/sidekiq', as: :sidekiq
end end
# Lint API
resources :lint, only: [:show, :create]
# Health check # Health check
get 'health_check(/:checks)' => 'health_check#index', as: :health_check get 'health_check(/:checks)' => 'health_check#index', as: :health_check
......
module API module API
class Lint < Grape::API class Lint < Grape::API
resource :lint do desc 'Validation of .gitlab-ci.yml content'
params do params do
requires :content, type: String, desc: 'Content of .gitlab-ci.yml' requires :content, type: String, desc: 'Content of .gitlab-ci.yml'
end end
desc 'Validation of .gitlab-ci.yml content'
post do
response = {
status: '',
error: [],
jobs: []
}
if Ci::GitlabCiYamlProcessor.errors(params[:content]).nil?
config_processor = Ci::GitlabCiYamlProcessor.new(params[:content])
config_processor.builds.each do |build| post 'ci/lint' do
response[:jobs].push("#{build[:name]}") error = Ci::GitlabCiYamlProcessor.validation_message(params[:content])
response[:status] = 'valid' response = {
end status: '',
else error: ''
response[:error].push(Ci::GitlabCiYamlProcessor.errors(params[:content])) }
response[:status] = 'invalid'
end
status 200 if error.blank?
response response[:status] = 'valid'
else
response[:error] = error
response[:status] = 'invalid'
end end
status 200
response
end end
end end
end end
...@@ -78,12 +78,16 @@ module Ci ...@@ -78,12 +78,16 @@ module Ci
} }
end end
def self.errors(content) def self.validation_message(content)
begin if content.blank?
Ci::GitlabCiYamlProcessor.new(content) 'Please provide content of .gitlab-ci.yml'
nil else
rescue ValidationError, Psych::SyntaxError => e begin
e.message Ci::GitlabCiYamlProcessor.new(content)
nil
rescue ValidationError, Psych::SyntaxError => e
e.message
end
end end
end end
......
...@@ -1252,20 +1252,33 @@ EOT ...@@ -1252,20 +1252,33 @@ EOT
end end
describe "#errors" do describe "#errors" do
describe "Error handling" do context "when the YAML could not be parsed" do
it "returns an error if the YAML could not be parsed" do it "returns an error about invalid configutaion" do
content = YAML.dump("invalid: yaml: test") content = YAML.dump("invalid: yaml: test")
expect(GitlabCiYamlProcessor.errors(content)).to eq "Invalid configuration format"
expect(GitlabCiYamlProcessor.validation_message(content)).to eq "Invalid configuration format"
end end
end
it "returns an error if the tags parameter is invalid" do context "when the tags parameter is invalid" do
it "returns an error about invalid tags" do
content = YAML.dump({ rspec: { script: "test", tags: "mysql" } }) content = YAML.dump({ rspec: { script: "test", tags: "mysql" } })
expect(GitlabCiYamlProcessor.errors(content)).to eq "jobs:rspec tags should be an array of strings"
expect(GitlabCiYamlProcessor.validation_message(content)).to eq "jobs:rspec tags should be an array of strings"
end
end
context "when YMAL content is empty" do
it "returns an error about missing content" do
expect(GitlabCiYamlProcessor.validation_message('')).to eq "Please provide content of .gitlab-ci.yml"
end end
end
it "does not return any errors when the YAML is valid" do context "when the YAML is valid" do
it "does not return any errors" do
content = File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml')) content = File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
expect(GitlabCiYamlProcessor.errors(content)).to eq nil
expect(GitlabCiYamlProcessor.validation_message(content)).to be_nil
end end
end end
end end
......
require 'spec_helper' require 'spec_helper'
describe API::API do describe API::Lint, api: true do
include ApiHelpers include ApiHelpers
let(:yaml_content) do describe 'POST /ci/lint' do
File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml')) let(:yaml_content) do
end File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
end
describe 'POST /lint' do
context 'with valid .gitlab-ci.yaml content' do context 'with valid .gitlab-ci.yaml content' do
it 'validates the content' do it 'passes validation' do
post api('/lint'), { content: yaml_content } post api('/ci/lint'), { content: yaml_content }
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(json_response).to be_an Hash expect(json_response).to be_an Hash
expect(json_response['status']).to eq('valid') expect(json_response['status']).to eq('valid')
expect(json_response['error']).to eq('')
end end
end end
context 'with an invalid .gitlab_ci.yml' do context 'with an invalid .gitlab_ci.yml' do
it 'validates the content and shows an error message' do it 'responds with errors about invalid syntax' do
post api('/lint'), { content: 'invalid content' } post api('/ci/lint'), { content: 'invalid content' }
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(json_response['status']).to eq('invalid') expect(json_response['status']).to eq('invalid')
expect(json_response['error']).to eq(['Invalid configuration format']) expect(json_response['error']).to eq('Invalid configuration format')
end end
it "validates the content and shows a configuration error" do it "responds with errors about invalid configuration" do
post api('/lint'), { content: '{ image: "ruby:2.1", services: ["postgres"] }' } post api('/ci/lint'), { content: '{ image: "ruby:2.1", services: ["postgres"] }' }
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(json_response['status']).to eq('invalid') expect(json_response['status']).to eq('invalid')
expect(json_response['error']).to eq(['jobs config should contain at least one visible job']) expect(json_response['error']).to eq('jobs config should contain at least one visible job')
end end
end end
context 'without the content parameter' do context 'without the content parameter' do
it 'shows an error message' do it 'responds with validation error about missing content' do
post api('/lint') post api('/ci/lint')
expect(response).to have_http_status(400) expect(response).to have_http_status(400)
expect(json_response['error']).to eq('content is missing') expect(json_response['error']).to eq('content is missing')
......
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