Commit dd6b4682 authored by Matija Čupić's avatar Matija Čupić

Refactor nested array of string validations

Refactors the nested array of string validations into separate
validators that can be reused.
parent 88799b2c
...@@ -109,7 +109,7 @@ describe Gitlab::WebIde::Config::Entry::Global do ...@@ -109,7 +109,7 @@ describe Gitlab::WebIde::Config::Entry::Global do
describe '#errors' do describe '#errors' do
it 'reports errors about missing script' do it 'reports errors about missing script' do
expect(global.errors) expect(global.errors)
.to include "terminal:before_script config should be an array of strings and arrays of strings" .to include "terminal:before_script config should be an array containing strings and arrays of strings"
end end
end end
end end
......
...@@ -11,16 +11,7 @@ module Gitlab ...@@ -11,16 +11,7 @@ module Gitlab
include ::Gitlab::Config::Entry::Validatable include ::Gitlab::Config::Entry::Validatable
validations do validations do
validate do validates :config, string_or_nested_array_of_strings: true
unless config.is_a?(String) ||
(config.is_a?(Array) && config.all? { |element| element.is_a?(String) || validate_array_of_strings?(element) })
errors.add(:config, 'should be a string or an array of strings and arrays of strings')
end
end
def validate_array_of_strings?(value)
value.is_a?(Array) && value.all? { |element| element.is_a?(String) }
end
end end
def value def value
......
...@@ -11,23 +11,11 @@ module Gitlab ...@@ -11,23 +11,11 @@ module Gitlab
include ::Gitlab::Config::Entry::Validatable include ::Gitlab::Config::Entry::Validatable
validations do validations do
validate do validates :config, nested_array_of_strings: true
unless config.is_a?(Array) && config.all? { |element| element.is_a?(String) || validate_array_of_strings?(element) }
errors.add(:config, 'should be an array of strings and arrays of strings')
end
end
def validate_array_of_strings?(value)
value.is_a?(Array) && value.all? { |element| element.is_a?(String) }
end
end end
def value def value
if config.is_a?(Array) config.flatten
config.flatten
else
config
end
end end
end end
end end
......
...@@ -228,6 +228,34 @@ module Gitlab ...@@ -228,6 +228,34 @@ module Gitlab
end end
end end
class NestedArrayOfStringsValidator < ArrayOfStringsOrStringValidator
def validate_each(record, attribute, value)
unless validate_nested_array_of_strings(value)
record.errors.add(attribute, 'should be an array containing strings and arrays of strings')
end
end
private
def validate_nested_array_of_strings(values)
values.is_a?(Array) && values.all? { |element| validate_array_of_strings_or_string(element) }
end
end
class StringOrNestedArrayOfStringsValidator < NestedArrayOfStringsValidator
def validate_each(record, attribute, value)
unless validate_string_or_nested_array_of_strings(value)
record.errors.add(attribute, 'should be a string or an array containing strings and arrays of strings')
end
end
private
def validate_string_or_nested_array_of_strings(values)
validate_string(values) || validate_nested_array_of_strings(values)
end
end
class TypeValidator < ActiveModel::EachValidator class TypeValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value) def validate_each(record, attribute, value)
type = options[:with] type = options[:with]
......
...@@ -87,7 +87,7 @@ describe Gitlab::Ci::Config::Entry::Commands do ...@@ -87,7 +87,7 @@ describe Gitlab::Ci::Config::Entry::Commands do
describe '#errors' do describe '#errors' do
it 'saves errors' do it 'saves errors' do
expect(entry.errors) expect(entry.errors)
.to include 'commands config should be a string or an array of strings and arrays of strings' .to include 'commands config should be a string or an array containing strings and arrays of strings'
end end
end end
end end
...@@ -98,7 +98,7 @@ describe Gitlab::Ci::Config::Entry::Commands do ...@@ -98,7 +98,7 @@ describe Gitlab::Ci::Config::Entry::Commands do
describe '#errors' do describe '#errors' do
it 'saves errors' do it 'saves errors' do
expect(entry.errors) expect(entry.errors)
.to include 'commands config should be a string or an array of strings and arrays of strings' .to include 'commands config should be a string or an array containing strings and arrays of strings'
end end
end end
......
...@@ -293,7 +293,7 @@ describe Gitlab::Ci::Config::Entry::Root do ...@@ -293,7 +293,7 @@ describe Gitlab::Ci::Config::Entry::Root do
describe '#errors' do describe '#errors' do
it 'reports errors from child nodes' do it 'reports errors from child nodes' do
expect(root.errors) expect(root.errors)
.to include 'before_script config should be an array of strings and arrays of strings' .to include 'before_script config should be an array containing strings and arrays of strings'
end end
end end
end end
......
...@@ -50,7 +50,7 @@ describe Gitlab::Ci::Config::Entry::Script do ...@@ -50,7 +50,7 @@ describe Gitlab::Ci::Config::Entry::Script do
end end
end end
context 'when entry config value is array of strings and arrays of strings' do context 'when entry config value is array containing strings and arrays of strings' do
let(:config) { ['ls', ['pwd', 'echo 1']] } let(:config) { ['ls', ['pwd', 'echo 1']] }
describe '#value' do describe '#value' do
...@@ -78,7 +78,7 @@ describe Gitlab::Ci::Config::Entry::Script do ...@@ -78,7 +78,7 @@ describe Gitlab::Ci::Config::Entry::Script do
describe '#errors' do describe '#errors' do
it 'saves errors' do it 'saves errors' do
expect(entry.errors) expect(entry.errors)
.to include 'script config should be an array of strings and arrays of strings' .to include 'script config should be an array containing strings and arrays of strings'
end end
end end
...@@ -95,7 +95,7 @@ describe Gitlab::Ci::Config::Entry::Script do ...@@ -95,7 +95,7 @@ describe Gitlab::Ci::Config::Entry::Script do
describe '#errors' do describe '#errors' do
it 'saves errors' do it 'saves errors' do
expect(entry.errors) expect(entry.errors)
.to include 'script config should be an array of strings and arrays of strings' .to include 'script config should be an array containing strings and arrays of strings'
end end
end end
......
...@@ -94,7 +94,7 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Config do ...@@ -94,7 +94,7 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Config do
it 'appends configuration validation errors to pipeline errors' do it 'appends configuration validation errors to pipeline errors' do
expect(pipeline.errors.to_a) expect(pipeline.errors.to_a)
.to include "jobs:rspec:before_script config should be an array of strings and arrays of strings" .to include "jobs:rspec:before_script config should be an array containing strings and arrays of strings"
end end
it 'breaks the chain' do it 'breaks the chain' do
......
...@@ -330,7 +330,7 @@ module Gitlab ...@@ -330,7 +330,7 @@ module Gitlab
} }
end end
it "return commands with scripts concencaced" do it "return commands with scripts concatenated" do
expect(subject[:options][:before_script]).to eq(["global script"]) expect(subject[:options][:before_script]).to eq(["global script"])
end end
end end
...@@ -343,7 +343,7 @@ module Gitlab ...@@ -343,7 +343,7 @@ module Gitlab
} }
end end
it "return commands with scripts concencaced" do it "return commands with scripts concatenated" do
expect(subject[:options][:before_script]).to eq(["global script"]) expect(subject[:options][:before_script]).to eq(["global script"])
end end
end end
...@@ -356,7 +356,7 @@ module Gitlab ...@@ -356,7 +356,7 @@ module Gitlab
} }
end end
it "return commands with scripts concencaced" do it "return commands with scripts concatenated" do
expect(subject[:options][:before_script]).to eq(["local script"]) expect(subject[:options][:before_script]).to eq(["local script"])
end end
end end
...@@ -369,7 +369,7 @@ module Gitlab ...@@ -369,7 +369,7 @@ module Gitlab
} }
end end
it "return commands with scripts concencaced" do it "return commands with scripts concatenated" do
expect(subject[:options][:before_script]).to eq(["global script", "echo 1", "ls", "pwd"]) expect(subject[:options][:before_script]).to eq(["global script", "echo 1", "ls", "pwd"])
end end
end end
...@@ -383,7 +383,7 @@ module Gitlab ...@@ -383,7 +383,7 @@ module Gitlab
} }
end end
it "return commands with scripts concencaced" do it "return commands with scripts concatenated" do
expect(subject[:options][:script]).to eq(["script"]) expect(subject[:options][:script]).to eq(["script"])
end end
end end
...@@ -395,7 +395,7 @@ module Gitlab ...@@ -395,7 +395,7 @@ module Gitlab
} }
end end
it "return commands with scripts concencaced" do it "return commands with scripts concatenated" do
expect(subject[:options][:script]).to eq(["script", "echo 1", "ls"]) expect(subject[:options][:script]).to eq(["script", "echo 1", "ls"])
end end
end end
...@@ -449,7 +449,7 @@ module Gitlab ...@@ -449,7 +449,7 @@ module Gitlab
} }
end end
it "return commands with scripts concencaced" do it "return after_script in options" do
expect(subject[:options][:after_script]).to eq(["global script", "echo 1", "ls", "pwd"]) expect(subject[:options][:after_script]).to eq(["global script", "echo 1", "ls", "pwd"])
end end
end end
...@@ -1587,42 +1587,42 @@ module Gitlab ...@@ -1587,42 +1587,42 @@ module Gitlab
config = YAML.dump({ before_script: "bundle update", rspec: { script: "test" } }) config = YAML.dump({ before_script: "bundle update", rspec: { script: "test" } })
expect do expect do
Gitlab::Ci::YamlProcessor.new(config) Gitlab::Ci::YamlProcessor.new(config)
end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "before_script config should be an array of strings and arrays of strings") end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "before_script config should be an array containing strings and arrays of strings")
end end
it "returns errors if job before_script parameter is not an array of strings" do it "returns errors if job before_script parameter is not an array of strings" do
config = YAML.dump({ rspec: { script: "test", before_script: [10, "test"] } }) config = YAML.dump({ rspec: { script: "test", before_script: [10, "test"] } })
expect do expect do
Gitlab::Ci::YamlProcessor.new(config) Gitlab::Ci::YamlProcessor.new(config)
end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "jobs:rspec:before_script config should be an array of strings and arrays of strings") end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "jobs:rspec:before_script config should be an array containing strings and arrays of strings")
end end
it "returns errors if job before_script parameter is multi-level nested array of strings" do it "returns errors if job before_script parameter is multi-level nested array of strings" do
config = YAML.dump({ rspec: { script: "test", before_script: [["ls", ["pwd"]], "test"] } }) config = YAML.dump({ rspec: { script: "test", before_script: [["ls", ["pwd"]], "test"] } })
expect do expect do
Gitlab::Ci::YamlProcessor.new(config) Gitlab::Ci::YamlProcessor.new(config)
end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "jobs:rspec:before_script config should be an array of strings and arrays of strings") end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "jobs:rspec:before_script config should be an array containing strings and arrays of strings")
end end
it "returns errors if after_script parameter is invalid" do it "returns errors if after_script parameter is invalid" do
config = YAML.dump({ after_script: "bundle update", rspec: { script: "test" } }) config = YAML.dump({ after_script: "bundle update", rspec: { script: "test" } })
expect do expect do
Gitlab::Ci::YamlProcessor.new(config) Gitlab::Ci::YamlProcessor.new(config)
end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "after_script config should be an array of strings and arrays of strings") end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "after_script config should be an array containing strings and arrays of strings")
end end
it "returns errors if job after_script parameter is not an array of strings" do it "returns errors if job after_script parameter is not an array of strings" do
config = YAML.dump({ rspec: { script: "test", after_script: [10, "test"] } }) config = YAML.dump({ rspec: { script: "test", after_script: [10, "test"] } })
expect do expect do
Gitlab::Ci::YamlProcessor.new(config) Gitlab::Ci::YamlProcessor.new(config)
end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "jobs:rspec:after_script config should be an array of strings and arrays of strings") end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "jobs:rspec:after_script config should be an array containing strings and arrays of strings")
end end
it "returns errors if job after_script parameter is multi-level nested array of strings" do it "returns errors if job after_script parameter is multi-level nested array of strings" do
config = YAML.dump({ rspec: { script: "test", after_script: [["ls", ["pwd"]], "test"] } }) config = YAML.dump({ rspec: { script: "test", after_script: [["ls", ["pwd"]], "test"] } })
expect do expect do
Gitlab::Ci::YamlProcessor.new(config) Gitlab::Ci::YamlProcessor.new(config)
end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "jobs:rspec:after_script config should be an array of strings and arrays of strings") end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "jobs:rspec:after_script config should be an array containing strings and arrays of strings")
end end
it "returns errors if image parameter is invalid" do it "returns errors if image parameter is invalid" do
......
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