spec/lib/nanoc/helpers/generic*_spec.rb (357 lines of code) (raw):
# frozen_string_literal: true
require 'spec_helper'
require 'nanoc'
require 'helpers/generic'
RSpec.describe Nanoc::Helpers::Generic do
let(:mock_class) { Class.new { extend Nanoc::Helpers::Generic } }
let(:path) { "ee/user/project/code_intelligence.html" }
let(:title) { "Code Intelligence" }
let(:mock_item) do
item = Struct.new(:title, :path)
item.new(title, path)
end
before do
mock_items = { '/_data/navigation.yaml' => YAML.load_file('spec/lib/fixtures/navigation-mock.yaml', symbolize_names: true) }
mock_sections = mock_items['/_data/navigation.yaml'][:sections]
allow(mock_class).to receive(:get_nav_sections).and_return(mock_sections)
end
describe '#docs_section' do
subject(:docs_section) { mock_class.docs_section(mock_item.title, mock_item.path, machine_readable) }
test_cases = [
{
path: "/ee/tutorials/",
title: "Learn GitLab with tutorials",
human_readable: "Tutorials",
machine_readable: "tutorials"
},
{
path: "/ee/ci/quick_start/",
title: "Tutorial: Create your first pipeline",
human_readable: "Tutorials",
machine_readable: "tutorials"
},
{
path: "/ee/topics/set_up_organization.html",
title: "Set up your organization",
human_readable: "Use GitLab",
machine_readable: "use_gitlab"
},
{
path: "/ee/user/project/autocomplete_characters.html",
title: "Autocomplete characters",
human_readable: "Use GitLab",
machine_readable: "use_gitlab"
},
{
path: "/ee/policy/alpha-beta-support.html",
title: "Support for Experiment, Beta, and Generally Available features",
human_readable: "Subscribe",
machine_readable: "subscribe"
},
{
path: "/updog.html",
title: "Test page",
human_readable: "none",
machine_readable: "none"
},
{
path: "/ee/administration/analytics.html",
title: "Use ClickHouse for analytics reports",
human_readable: "Markdown _formatting_ & `special characters`",
machine_readable: "markdown_formatting_special_characters"
}
]
test_cases.each do |test_case|
context "with path: #{test_case[:path]}" do
let(:title) { test_case[:title] }
let(:path) { test_case[:path] }
before do
allow(mock_class).to receive(:find_section).with(test_case[:title], test_case[:path]).and_return(test_case[:human_readable])
end
context "when machine_readable is false" do
let(:machine_readable) { false }
it "returns the human-readable section title" do
expect(docs_section).to eq(test_case[:human_readable])
end
end
context "when machine_readable is true" do
let(:machine_readable) { true }
it "returns the machine-readable section title" do
expect(docs_section).to eq(test_case[:machine_readable])
end
end
end
end
end
describe '#build_breadcrumb_list' do
# Test all six levels of the menu
let(:test_data) do
[
{
path: '/ee/user/',
expected_items: [
{
'@type': "ListItem",
position: 1,
name: "Use GitLab"
}
]
},
{
path: '/ee/topics/set_up_organization.html',
expected_items: [
{
'@type': "ListItem",
position: 1,
name: "Use GitLab",
item: "https://docs.gitlab.com/ee/user/"
},
{
'@type': "ListItem",
position: 2,
name: "Set up your organization"
}
]
},
{
path: '/ee/user/namespace/',
expected_items: [
{
'@type': "ListItem",
position: 1,
name: "Use GitLab",
item: "https://docs.gitlab.com/ee/user/"
},
{
'@type': "ListItem",
position: 2,
name: "Set up your organization",
item: "https://docs.gitlab.com/ee/topics/set_up_organization.html"
},
{
'@type': "ListItem",
position: 3,
name: "Namespaces"
}
]
},
{
path: '/ee/user/group/manage.html',
expected_items: [
{
'@type': "ListItem",
position: 1,
name: "Use GitLab",
item: "https://docs.gitlab.com/ee/user/"
},
{
'@type': "ListItem",
position: 2,
name: "Set up your organization",
item: "https://docs.gitlab.com/ee/topics/set_up_organization.html"
},
{
'@type': "ListItem",
position: 3,
name: "Groups",
item: "https://docs.gitlab.com/ee/user/group/"
},
{
'@type': "ListItem",
position: 4,
name: "Manage groups"
}
]
},
{
path: '/ee/user/group/saml_sso/scim_setup.html',
expected_items: [
{
'@type': "ListItem",
position: 1,
name: "Use GitLab",
item: "https://docs.gitlab.com/ee/user/"
},
{
'@type': "ListItem",
position: 2,
name: "Set up your organization",
item: "https://docs.gitlab.com/ee/topics/set_up_organization.html"
},
{
'@type': "ListItem",
position: 3,
name: "Groups",
item: "https://docs.gitlab.com/ee/user/group/"
},
{
'@type': "ListItem",
position: 4,
name: "SAML SSO for GitLab.com groups",
item: "https://docs.gitlab.com/ee/user/group/saml_sso/"
},
{
'@type': "ListItem",
position: 5,
name: "Configure SCIM"
}
]
},
{
path: '/ee/topics/autodevops/cicd_variables.html',
expected_items: [
{
'@type': "ListItem",
position: 1,
name: "Use GitLab",
item: "https://docs.gitlab.com/ee/user/"
},
{
'@type': "ListItem",
position: 2,
name: "Build your application",
item: "https://docs.gitlab.com/ee/topics/build_your_application.html"
},
{
'@type': "ListItem",
position: 3,
name: "CI/CD",
item: "https://docs.gitlab.com/ee/ci/"
},
{
'@type': "ListItem",
position: 4,
name: "Auto DevOps",
item: "https://docs.gitlab.com/ee/topics/autodevops/"
},
{
'@type': "ListItem",
position: 5,
name: "Customize",
item: "https://docs.gitlab.com/ee/topics/autodevops/customize.html"
},
{
'@type': "ListItem",
position: 6,
name: "CI/CD variables"
}
]
}
]
end
it 'returns an array of menu items in schema.org breadcrumblist format' do
test_data.each do |data|
expected_items = data[:expected_items]
expected_json = {
'@context': "https://schema.org",
'@type': "BreadcrumbList",
itemListElement: expected_items
}
param_value = data[:path]
expect(mock_class.build_breadcrumb_list(param_value)).to eq(expected_json)
end
end
end
describe '#docs_breadcrumb_list' do
using RSpec::Parameterized::TableSyntax
subject(:docs_breadcrumb_list) { mock_class.docs_breadcrumb_list(mock_item.path) }
where(:path, :expected_breadcrumb_list) do
"/ee/tutorials/" | "Tutorials"
"/ee/topics/set_up_organization.html" | "Use GitLab › Set up your organization"
"/ee/user/project/autocomplete_characters.html" | "Use GitLab › Plan and track work › Quick actions › Autocomplete characters"
"/ee/user/project/settings/import_export_troubleshooting.html" | "Use GitLab › Organize work with projects › Migrate projects using file exports › Troubleshooting"
"/updog.html" | ""
end
with_them do
it "returns the breadcrumb trail for the given path" do
expect(docs_breadcrumb_list).to eq(expected_breadcrumb_list)
end
end
end
describe '#get_release_dates' do
subject(:release_dates) { mock_class.get_release_dates }
valid_yaml_content = "- version: '18.0'\n date: '2025-05-15'"
invalid_yaml_content = "version: '18.0'date: 2025-05-15'"
it 'returns a JSON array when the YAML is valid' do
allow(Net::HTTP).to receive(:get_response).and_return(Net::HTTPSuccess.new('1.1', '200', 'OK'))
allow_any_instance_of(Net::HTTPSuccess).to receive(:body).and_return(valid_yaml_content)
expect(release_dates).to be_a(String)
end
it 'returns an empty JSON array when the YAML is invalid' do
allow(Net::HTTP).to receive(:get_response).and_return(Net::HTTPSuccess.new('1.1', '200', 'OK'))
allow_any_instance_of(Net::HTTPSuccess).to receive(:body).and_return(invalid_yaml_content)
allow(mock_class).to receive(:warn).with('Error getting release dates - (<unknown>): did not find expected key while parsing a block mapping at line 1 column 1')
expect(release_dates).to eq("[]")
end
it 'returns an empty JSON array on HTTP error' do
allow(Net::HTTP).to receive(:get_response).and_return(Net::HTTPServerError.new('1.1', '500', 'Internal Server Error'))
expect(release_dates).to eq("[]")
end
it 'returns an empty JSON array on other errors' do
allow(Net::HTTP).to receive(:get_response).and_raise(StandardError.new('Some error message'))
allow(mock_class).to receive(:warn).with('Error getting release dates - Some error message')
expect(release_dates).to eq("[]")
end
end
describe '#gitlab_analytics_enabled?' do
context 'when GITLAB_ANALYTICS_HOST and GITLAB_ANALYTICS_ID are set' do
before do
ENV['GITLAB_ANALYTICS_HOST'] = 'https://collector.com'
ENV['GITLAB_ANALYTICS_ID'] = '123'
end
it 'returns true' do
expect(mock_class.gitlab_analytics_enabled?).to be_truthy
end
end
context 'when only GITLAB_ANALYTICS_HOST is set' do
before do
ENV['GITLAB_ANALYTICS_HOST'] = 'https://collector.com'
ENV['GITLAB_ANALYTICS_ID'] = nil
end
it 'returns false' do
expect(mock_class.gitlab_analytics_enabled?).to be_falsey
end
end
context 'when only GITLAB_ANALYTICS_ID is set' do
before do
ENV['GITLAB_ANALYTICS_HOST'] = nil
ENV['GITLAB_ANALYTICS_ID'] = '123'
end
it 'returns false' do
expect(mock_class.gitlab_analytics_enabled?).to be_falsey
end
end
context 'when neither GITLAB_ANALYTICS_HOST nor GITLAB_ANALYTICS_ID are set' do
before do
ENV['GITLAB_ANALYTICS_HOST'] = nil
ENV['GITLAB_ANALYTICS_ID'] = nil
end
it 'returns false' do
expect(mock_class.gitlab_analytics_enabled?).to be_falsey
end
end
end
describe '#gitlab_analytics_json' do
context 'when gitlab analytics is enabled' do
before do
ENV['GITLAB_ANALYTICS_ID'] = '123'
ENV['GITLAB_ANALYTICS_HOST'] = 'https://collector.com'
allow(mock_class).to receive(:gitlab_analytics_enabled?).and_return(true)
end
it 'returns the configuration object' do
expected_json = {
'appId' => '123',
'host' => 'https://collector.com',
'hasCookieConsent' => true
}.to_json
expect(mock_class.gitlab_analytics_json).to eq(expected_json)
end
end
context 'when gitlab analytics is not enabled' do
before do
allow(mock_class).to receive(:gitlab_analytics_enabled?).and_return(false)
end
it 'returns nil' do
expect(mock_class.gitlab_analytics_json).to be_nil
end
end
end
end