Commit b0156810 authored by Stan Hu's avatar Stan Hu

Raise issuable text limits

The 16,000 and 48,000-byte description and description HTML limits were
a bit too low. In some of our onboarding tasks, the text took close to
170K.

Our API limits the description to be 1 megabyte, so update the limit to
match that. From
https://gitlab.com/gitlab-org/gitlab/merge_requests/16181, the estimated
description HTML multiple was 3x, so make this limit 5x to give some
leeway.
parent c3ea95db
...@@ -28,8 +28,8 @@ module Issuable ...@@ -28,8 +28,8 @@ module Issuable
TITLE_LENGTH_MAX = 255 TITLE_LENGTH_MAX = 255
TITLE_HTML_LENGTH_MAX = 800 TITLE_HTML_LENGTH_MAX = 800
DESCRIPTION_LENGTH_MAX = 16000 DESCRIPTION_LENGTH_MAX = 1.megabyte
DESCRIPTION_HTML_LENGTH_MAX = 48000 DESCRIPTION_HTML_LENGTH_MAX = 5.megabytes
# This object is used to gather issuable meta data for displaying # This object is used to gather issuable meta data for displaying
# upvotes, downvotes, notes and closing merge requests count for issues and merge requests # upvotes, downvotes, notes and closing merge requests count for issues and merge requests
......
...@@ -11,8 +11,8 @@ There are max length constraints for the most important text fields for `Issuabl ...@@ -11,8 +11,8 @@ There are max length constraints for the most important text fields for `Issuabl
- `title`: 255 chars - `title`: 255 chars
- `title_html`: 800 chars - `title_html`: 800 chars
- `description`: 16000 chars - `description`: 1 megabyte
- `description_html`: 48000 chars - `description_html`: 5 megabytes
[Issue]: https://docs.gitlab.com/ee/user/project/issues [Issue]: https://docs.gitlab.com/ee/user/project/issues
[Merge Requests]: https://docs.gitlab.com/ee/user/project/merge_requests [Merge Requests]: https://docs.gitlab.com/ee/user/project/merge_requests
......
...@@ -14,8 +14,8 @@ describe EE::Issuable do ...@@ -14,8 +14,8 @@ describe EE::Issuable do
it { is_expected.to validate_presence_of(:iid) } it { is_expected.to validate_presence_of(:iid) }
it { is_expected.to validate_presence_of(:author) } it { is_expected.to validate_presence_of(:author) }
it { is_expected.to validate_presence_of(:title) } it { is_expected.to validate_presence_of(:title) }
it { is_expected.to validate_length_of(:title).is_at_most(255) } it { is_expected.to validate_length_of(:title).is_at_most(::Issuable::TITLE_LENGTH_MAX) }
it { is_expected.to validate_length_of(:description).is_at_most(16_000).on(:create) } it { is_expected.to validate_length_of(:description).is_at_most(::Issuable::DESCRIPTION_LENGTH_MAX).on(:create) }
it_behaves_like 'validates description length with custom validation' it_behaves_like 'validates description length with custom validation'
it_behaves_like 'truncates the description to its allowed maximum length on import' it_behaves_like 'truncates the description to its allowed maximum length on import'
......
...@@ -50,9 +50,9 @@ describe Vulnerability do ...@@ -50,9 +50,9 @@ describe Vulnerability do
it { is_expected.to validate_presence_of(:severity) } it { is_expected.to validate_presence_of(:severity) }
it { is_expected.to validate_presence_of(:confidence) } it { is_expected.to validate_presence_of(:confidence) }
it { is_expected.to validate_length_of(:title).is_at_most(255) } it { is_expected.to validate_length_of(:title).is_at_most(::Issuable::TITLE_LENGTH_MAX) }
it { is_expected.to validate_length_of(:title_html).is_at_most(800) } it { is_expected.to validate_length_of(:title_html).is_at_most(::Issuable::TITLE_HTML_LENGTH_MAX) }
it { is_expected.to validate_length_of(:description).is_at_most(16_000).allow_nil } it { is_expected.to validate_length_of(:description).is_at_most(::Issuable::DESCRIPTION_LENGTH_MAX).allow_nil }
it { is_expected.to validate_length_of(:description_html).is_at_most(48_000).allow_nil } it { is_expected.to validate_length_of(:description_html).is_at_most(::Issuable::DESCRIPTION_HTML_LENGTH_MAX).allow_nil }
end end
end end
...@@ -45,8 +45,8 @@ describe Issuable do ...@@ -45,8 +45,8 @@ describe Issuable do
it { is_expected.to validate_presence_of(:iid) } it { is_expected.to validate_presence_of(:iid) }
it { is_expected.to validate_presence_of(:author) } it { is_expected.to validate_presence_of(:author) }
it { is_expected.to validate_presence_of(:title) } it { is_expected.to validate_presence_of(:title) }
it { is_expected.to validate_length_of(:title).is_at_most(255) } it { is_expected.to validate_length_of(:title).is_at_most(described_class::TITLE_LENGTH_MAX) }
it { is_expected.to validate_length_of(:description).is_at_most(16_000).on(:create) } it { is_expected.to validate_length_of(:description).is_at_most(described_class::DESCRIPTION_LENGTH_MAX).on(:create) }
it_behaves_like 'validates description length with custom validation' it_behaves_like 'validates description length with custom validation'
it_behaves_like 'truncates the description to its allowed maximum length on import' it_behaves_like 'truncates the description to its allowed maximum length on import'
......
...@@ -10,7 +10,7 @@ shared_examples_for 'matches_cross_reference_regex? fails fast' do ...@@ -10,7 +10,7 @@ shared_examples_for 'matches_cross_reference_regex? fails fast' do
end end
shared_examples_for 'validates description length with custom validation' do shared_examples_for 'validates description length with custom validation' do
let(:issuable) { build(:issue, description: 'x' * 16_001) } let(:issuable) { build(:issue, description: 'x' * (::Issuable::DESCRIPTION_LENGTH_MAX + 1)) }
let(:context) { :update } let(:context) { :update }
subject { issuable.validate(context) } subject { issuable.validate(context) }
...@@ -18,7 +18,7 @@ shared_examples_for 'validates description length with custom validation' do ...@@ -18,7 +18,7 @@ shared_examples_for 'validates description length with custom validation' do
context 'when Issuable is a new record' do context 'when Issuable is a new record' do
it 'validates the maximum description length' do it 'validates the maximum description length' do
subject subject
expect(issuable.errors[:description]).to eq(["is too long (maximum is 16000 characters)"]) expect(issuable.errors[:description]).to eq(["is too long (maximum is #{::Issuable::DESCRIPTION_LENGTH_MAX} characters)"])
end end
context 'on create' do context 'on create' do
...@@ -53,14 +53,14 @@ shared_examples_for 'truncates the description to its allowed maximum length on ...@@ -53,14 +53,14 @@ shared_examples_for 'truncates the description to its allowed maximum length on
allow(issuable).to receive(:importing?).and_return(true) allow(issuable).to receive(:importing?).and_return(true)
end end
let(:issuable) { build(:issue, description: 'x' * 16_001) } let(:issuable) { build(:issue, description: 'x' * (::Issuable::DESCRIPTION_LENGTH_MAX + 1)) }
subject { issuable.validate(:create) } subject { issuable.validate(:create) }
it 'truncates the description to its allowed maximum length' do it 'truncates the description to its allowed maximum length' do
subject subject
expect(issuable.description).to eq('x' * 16_000) expect(issuable.description).to eq('x' * ::Issuable::DESCRIPTION_LENGTH_MAX)
expect(issuable.errors[:description]).to be_empty expect(issuable.errors[:description]).to be_empty
end end
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