271 lines
5.7 KiB
Ruby
271 lines
5.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'spec_helper'
|
|
|
|
RSpec.describe Gitlab::WikiPages::FrontMatterParser do
|
|
subject(:parser) { described_class.new(raw_content, gate) }
|
|
|
|
let(:content) { 'This is the content' }
|
|
let(:end_divider) { '---' }
|
|
let(:gate) { stub_feature_flag_gate('Gate') }
|
|
|
|
let(:with_front_matter) do
|
|
<<~MD
|
|
---
|
|
a: 1
|
|
b: 2
|
|
c:
|
|
- foo
|
|
- bar
|
|
date: I am safe. Not actually a date
|
|
#{end_divider}
|
|
#{content}
|
|
MD
|
|
end
|
|
|
|
def have_correct_front_matter
|
|
include(a: 1, b: 2, c: %w(foo bar))
|
|
end
|
|
|
|
describe '#parse' do
|
|
subject { parser.parse }
|
|
|
|
context 'there is front matter' do
|
|
let(:raw_content) { with_front_matter }
|
|
|
|
it do
|
|
is_expected.to have_attributes(
|
|
front_matter: have_correct_front_matter,
|
|
content: content + "\n",
|
|
error: be_nil
|
|
)
|
|
end
|
|
end
|
|
|
|
context 'there is no content' do
|
|
let(:raw_content) { '' }
|
|
|
|
it do
|
|
is_expected.to have_attributes(
|
|
front_matter: {},
|
|
content: raw_content,
|
|
error: be_nil
|
|
)
|
|
end
|
|
end
|
|
|
|
context 'there is no front_matter' do
|
|
let(:raw_content) { content }
|
|
|
|
it { is_expected.to have_attributes(front_matter: be_empty, content: raw_content) }
|
|
|
|
it { is_expected.to have_attributes(reason: :no_match) }
|
|
end
|
|
|
|
context 'the feature flag is disabled' do
|
|
let(:raw_content) { with_front_matter }
|
|
|
|
before do
|
|
stub_feature_flags(Gitlab::WikiPages::FrontMatterParser::FEATURE_FLAG => false)
|
|
end
|
|
|
|
it { is_expected.to have_attributes(front_matter: be_empty, content: raw_content) }
|
|
end
|
|
|
|
context 'the feature flag is enabled for the gated object' do
|
|
let(:raw_content) { with_front_matter }
|
|
|
|
before do
|
|
stub_feature_flags(Gitlab::WikiPages::FrontMatterParser::FEATURE_FLAG => gate)
|
|
end
|
|
|
|
it do
|
|
is_expected.to have_attributes(
|
|
front_matter: have_correct_front_matter,
|
|
content: content + "\n",
|
|
reason: be_nil
|
|
)
|
|
end
|
|
end
|
|
|
|
context 'the end divider is ...' do
|
|
let(:end_divider) { '...' }
|
|
let(:raw_content) { with_front_matter }
|
|
|
|
it { is_expected.to have_attributes(front_matter: have_correct_front_matter) }
|
|
end
|
|
|
|
context 'the front-matter is not a mapping' do
|
|
let(:raw_content) do
|
|
<<~MD
|
|
---
|
|
- thing one
|
|
- thing two
|
|
---
|
|
#{content}
|
|
MD
|
|
end
|
|
|
|
it { is_expected.to have_attributes(reason: :not_mapping) }
|
|
end
|
|
|
|
context 'there is nothing in the front-matter block' do
|
|
let(:raw_content) do
|
|
<<~MD
|
|
---
|
|
---
|
|
My content here
|
|
MD
|
|
end
|
|
|
|
it { is_expected.to have_attributes(reason: :not_mapping) }
|
|
end
|
|
|
|
context 'there is a string in the YAML block' do
|
|
let(:raw_content) do
|
|
<<~MD
|
|
---
|
|
This is a string
|
|
---
|
|
#{content}
|
|
MD
|
|
end
|
|
|
|
it { is_expected.to have_attributes(reason: :not_mapping) }
|
|
end
|
|
|
|
context 'there is dangerous YAML in the block' do
|
|
let(:raw_content) do
|
|
<<~MD
|
|
---
|
|
date: 2010-02-11 11:02:57
|
|
---
|
|
#{content}
|
|
MD
|
|
end
|
|
|
|
it { is_expected.to have_attributes(reason: :parse_error, error: be_present) }
|
|
end
|
|
|
|
context 'there is acceptably long YAML in the front-matter block' do
|
|
let(:raw_content) do
|
|
key = 'title: '
|
|
length = described_class::MAX_FRONT_MATTER_LENGTH - key.size
|
|
|
|
<<~MD
|
|
---
|
|
title: #{FFaker::Lorem.characters(length)}
|
|
---
|
|
#{content}
|
|
MD
|
|
end
|
|
|
|
it { is_expected.to have_attributes(front_matter: include(title: be_present)) }
|
|
end
|
|
|
|
context 'there is suspiciously long YAML in the front-matter block' do
|
|
let(:raw_content) do
|
|
<<~MD
|
|
---
|
|
title: #{FFaker::Lorem.characters(described_class::MAX_FRONT_MATTER_LENGTH)}
|
|
---
|
|
#{content}
|
|
MD
|
|
end
|
|
|
|
it { is_expected.to have_attributes(reason: :too_long) }
|
|
end
|
|
|
|
context 'TOML front matter' do
|
|
let(:raw_content) do
|
|
<<~MD
|
|
+++
|
|
title = "My title"
|
|
+++
|
|
#{content}
|
|
MD
|
|
end
|
|
|
|
it { is_expected.to have_attributes(reason: :not_yaml) }
|
|
end
|
|
|
|
context 'TOML style fences, advertised as YAML' do
|
|
let(:raw_content) do
|
|
<<~MD
|
|
+++ yaml
|
|
title: "My title"
|
|
+++
|
|
#{content}
|
|
MD
|
|
end
|
|
|
|
it { is_expected.to have_attributes(front_matter: include(title: 'My title')) }
|
|
end
|
|
|
|
context 'YAML, advertised as something else' do
|
|
let(:raw_content) do
|
|
<<~MD
|
|
--- toml
|
|
title: My title
|
|
---
|
|
#{content}
|
|
MD
|
|
end
|
|
|
|
it { is_expected.to have_attributes(reason: :not_yaml) }
|
|
end
|
|
|
|
context 'there is text content in the YAML block, in comments' do
|
|
let(:raw_content) do
|
|
<<~MD
|
|
---
|
|
# This is YAML
|
|
#
|
|
# It has comments though. Explaining things
|
|
foo: 1
|
|
|
|
## It has headings
|
|
|
|
headings:
|
|
|
|
- heading one
|
|
- heading two
|
|
|
|
# And lists
|
|
|
|
lists:
|
|
|
|
- and lists
|
|
- with things in them
|
|
---
|
|
#{content}
|
|
MD
|
|
end
|
|
|
|
it { is_expected.to have_attributes(front_matter: include(foo: 1)) }
|
|
end
|
|
|
|
context 'there is text content in the YAML block' do
|
|
let(:raw_content) do
|
|
<<~MD
|
|
---
|
|
# This is not YAML
|
|
|
|
In fact is looks like markdown
|
|
|
|
## It has headings
|
|
|
|
Paragraphs
|
|
|
|
- and lists
|
|
- with things in them
|
|
---
|
|
#{content}
|
|
MD
|
|
end
|
|
|
|
it { is_expected.to have_attributes(reason: :not_mapping) }
|
|
end
|
|
end
|
|
end
|