nesta 0.11.1 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/workflows/tests.yml +21 -0
- data/.gitmodules +0 -0
- data/CHANGES +44 -2
- data/Gemfile +1 -1
- data/Gemfile.lock +73 -55
- data/LICENSE +1 -1
- data/README.md +7 -14
- data/RELEASING.md +10 -9
- data/Rakefile +20 -3
- data/bin/nesta +1 -1
- data/config/deploy.rb.sample +1 -1
- data/lib/nesta/app.rb +4 -8
- data/lib/nesta/commands/demo/content.rb +28 -12
- data/lib/nesta/commands/edit.rb +2 -6
- data/lib/nesta/commands/new.rb +9 -11
- data/lib/nesta/commands/plugin/create.rb +7 -9
- data/lib/nesta/commands/template.rb +20 -0
- data/lib/nesta/commands/theme/create.rb +8 -8
- data/lib/nesta/commands/theme/enable.rb +3 -5
- data/lib/nesta/commands/theme/install.rb +12 -14
- data/lib/nesta/commands.rb +8 -0
- data/lib/nesta/config_file.rb +25 -0
- data/lib/nesta/helpers.rb +14 -0
- data/lib/nesta/models.rb +26 -22
- data/lib/nesta/navigation.rb +1 -1
- data/lib/nesta/system_command.rb +15 -0
- data/lib/nesta/version.rb +1 -1
- data/lib/nesta.rb +6 -1
- data/nesta.gemspec +11 -12
- data/templates/config/config.yml +1 -1
- data/{spec → test}/fixtures/nesta-plugin-test/Gemfile +0 -0
- data/{spec → test}/fixtures/nesta-plugin-test/Rakefile +0 -0
- data/{spec → test}/fixtures/nesta-plugin-test/lib/nesta-plugin-test/init.rb +0 -0
- data/{spec → test}/fixtures/nesta-plugin-test/lib/nesta-plugin-test/version.rb +0 -0
- data/{spec → test}/fixtures/nesta-plugin-test/lib/nesta-plugin-test.rb +0 -0
- data/{spec → test}/fixtures/nesta-plugin-test/nesta-plugin-test.gemspec +0 -0
- data/test/integration/atom_feed_test.rb +178 -0
- data/test/integration/commands/demo/content_test.rb +33 -0
- data/test/integration/commands/edit_test.rb +21 -0
- data/test/integration/commands/new_test.rb +91 -0
- data/test/integration/commands/plugin/create_test.rb +131 -0
- data/test/integration/commands/theme/create_test.rb +41 -0
- data/test/integration/commands/theme/enable_test.rb +28 -0
- data/test/integration/commands/theme/install_test.rb +66 -0
- data/test/integration/default_theme_test.rb +220 -0
- data/test/integration/overrides_test.rb +118 -0
- data/test/integration/route_handlers_test.rb +96 -0
- data/test/integration/sitemap_test.rb +85 -0
- data/test/integration_test_helper.rb +61 -0
- data/test/support/model_factory.rb +169 -0
- data/test/support/temporary_files.rb +33 -0
- data/test/support/test_configuration.rb +19 -0
- data/test/test_helper.rb +26 -0
- data/test/unit/config_test.rb +138 -0
- data/test/unit/file_model_test.rb +71 -0
- data/test/unit/menu_test.rb +82 -0
- data/test/unit/page_test.rb +571 -0
- data/test/unit/path_test.rb +41 -0
- data/test/unit/plugin_test.rb +47 -0
- data/test/unit/system_command_test.rb +20 -0
- data/views/master.sass +1 -1
- metadata +90 -89
- data/.hound.yml +0 -2
- data/.rspec +0 -1
- data/.travis.yml +0 -6
- data/lib/nesta/commands/command.rb +0 -58
- data/smoke-test.sh +0 -107
- data/spec/atom_spec.rb +0 -141
- data/spec/commands/demo/content_spec.rb +0 -65
- data/spec/commands/edit_spec.rb +0 -27
- data/spec/commands/new_spec.rb +0 -88
- data/spec/commands/plugin/create_spec.rb +0 -97
- data/spec/commands/system_spec.rb +0 -25
- data/spec/commands/theme/create_spec.rb +0 -41
- data/spec/commands/theme/enable_spec.rb +0 -44
- data/spec/commands/theme/install_spec.rb +0 -56
- data/spec/config_spec.rb +0 -127
- data/spec/model_factory.rb +0 -92
- data/spec/models_spec.rb +0 -700
- data/spec/overrides_spec.rb +0 -132
- data/spec/page_spec.rb +0 -560
- data/spec/path_spec.rb +0 -28
- data/spec/plugin_spec.rb +0 -51
- data/spec/sitemap_spec.rb +0 -105
- data/spec/spec_helper.rb +0 -114
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'integration_test_helper'
|
2
|
+
|
3
|
+
describe 'XML sitemap' do
|
4
|
+
include Nesta::IntegrationTest
|
5
|
+
|
6
|
+
def visit_sitemap
|
7
|
+
visit '/sitemap.xml'
|
8
|
+
end
|
9
|
+
|
10
|
+
def for_site_with_page(&block)
|
11
|
+
with_temp_content_directory do
|
12
|
+
model = create(:page)
|
13
|
+
visit_sitemap
|
14
|
+
yield(model)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def for_site_with_article(&block)
|
19
|
+
with_temp_content_directory do
|
20
|
+
article = create(:article)
|
21
|
+
visit_sitemap
|
22
|
+
yield(article)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'renders successfully' do
|
27
|
+
for_site_with_page do
|
28
|
+
assert_equal 200, page.status_code
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'has a urlset tag' do
|
33
|
+
for_site_with_page do
|
34
|
+
namespace = 'http://www.sitemaps.org/schemas/sitemap/0.9'
|
35
|
+
assert_has_xpath "//urlset[@xmlns='#{namespace}']"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'references the home page' do
|
40
|
+
for_site_with_page do
|
41
|
+
assert_has_xpath '//urlset/url/loc', text: 'http://www.example.com/'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'configures home page to be checked frequently' do
|
46
|
+
for_site_with_page do
|
47
|
+
assert_has_xpath '//urlset/url/loc', text: "http://www.example.com/"
|
48
|
+
assert_has_xpath '//urlset/url/changefreq', text: "daily"
|
49
|
+
assert_has_xpath '//urlset/url/priority', text: "1.0"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it "sets homepage lastmod from timestamp of most recently modified page" do
|
54
|
+
for_site_with_article do |article|
|
55
|
+
timestamp = article.last_modified
|
56
|
+
assert_has_xpath '//urlset/url/loc', text: "http://www.example.com/"
|
57
|
+
assert_has_xpath '//urlset/url/lastmod', text: timestamp.xmlschema
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def site_url(path)
|
62
|
+
"http://www.example.com/#{path}"
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'references category pages' do
|
66
|
+
for_site_with_page do |model|
|
67
|
+
assert_has_xpath '//urlset/url/loc', text: site_url(model.path)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'references article pages' do
|
72
|
+
for_site_with_article do |article|
|
73
|
+
assert_has_xpath '//urlset/url/loc', text: site_url(article.path)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'omits pages that have the skip-sitemap flag set' do
|
78
|
+
with_temp_content_directory do
|
79
|
+
create(:category)
|
80
|
+
omitted = create(:page, metadata: { 'flags' => 'skip-sitemap' })
|
81
|
+
visit_sitemap
|
82
|
+
assert_has_no_xpath '//urlset/url/loc', text: site_url(omitted.path)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'capybara/dsl'
|
2
|
+
|
3
|
+
require_relative 'test_helper'
|
4
|
+
|
5
|
+
module Nesta
|
6
|
+
class App < Sinatra::Base
|
7
|
+
set :environment, :test
|
8
|
+
set :reload_templates, true
|
9
|
+
end
|
10
|
+
|
11
|
+
module IntegrationTest
|
12
|
+
include Capybara::DSL
|
13
|
+
|
14
|
+
include ModelFactory
|
15
|
+
include TestConfiguration
|
16
|
+
|
17
|
+
def setup
|
18
|
+
Capybara.app = App.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def teardown
|
22
|
+
Capybara.reset_sessions!
|
23
|
+
Capybara.use_default_driver
|
24
|
+
|
25
|
+
remove_temp_directory
|
26
|
+
Nesta::FileModel.purge_cache
|
27
|
+
end
|
28
|
+
|
29
|
+
def assert_has_xpath(query, options = {})
|
30
|
+
if ! page.has_xpath?(query, options)
|
31
|
+
message = "not found in page: '#{query}'"
|
32
|
+
message << ", #{options.inspect}" unless options.empty?
|
33
|
+
fail message
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def assert_has_no_xpath(query, options = {})
|
38
|
+
if page.has_xpath?(query, options)
|
39
|
+
message = "found in page: '#{query}'"
|
40
|
+
message << ", #{options.inspect}" unless options.empty?
|
41
|
+
fail message
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def assert_has_css(query, options = {})
|
46
|
+
if ! page.has_css?(query, options)
|
47
|
+
message = "not found in page: '#{query}'"
|
48
|
+
message << ", #{options.inspect}" unless options.empty?
|
49
|
+
fail message
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def assert_has_no_css(query, options = {})
|
54
|
+
if ! page.has_no_css?(query, options)
|
55
|
+
message = "found in page: '#{query}'"
|
56
|
+
message << ", #{options.inspect}" unless options.empty?
|
57
|
+
fail message
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
module ModelFactory
|
2
|
+
class FileModelWriter
|
3
|
+
def initialize(type, data = {})
|
4
|
+
@type = type
|
5
|
+
@data = data
|
6
|
+
end
|
7
|
+
|
8
|
+
def model_class
|
9
|
+
Nesta::FileModel
|
10
|
+
end
|
11
|
+
|
12
|
+
def instantiate_model
|
13
|
+
model_class.new(filename)
|
14
|
+
end
|
15
|
+
|
16
|
+
def extension
|
17
|
+
data.fetch(:ext, 'mdown')
|
18
|
+
end
|
19
|
+
|
20
|
+
def filename
|
21
|
+
File.join(model_class.model_path, "#{data[:path]}.#{extension}")
|
22
|
+
end
|
23
|
+
|
24
|
+
def sequence_prefix
|
25
|
+
'file-'
|
26
|
+
end
|
27
|
+
|
28
|
+
def default_data
|
29
|
+
{ path: default_path }
|
30
|
+
end
|
31
|
+
|
32
|
+
def default_path
|
33
|
+
sequence_prefix + ModelFactory.next_sequence_number.to_s
|
34
|
+
end
|
35
|
+
|
36
|
+
def data
|
37
|
+
if @memoized_data.nil?
|
38
|
+
@memoized_data = default_data
|
39
|
+
if @memoized_data.has_key?(:metadata)
|
40
|
+
@memoized_data[:metadata].merge!(@data.delete(:metadata) || {})
|
41
|
+
end
|
42
|
+
@memoized_data.merge!(@data)
|
43
|
+
end
|
44
|
+
@memoized_data
|
45
|
+
end
|
46
|
+
|
47
|
+
def write
|
48
|
+
metadata = data[:metadata] || {}
|
49
|
+
metatext = metadata.map { |key, value| "#{key}: #{value}" }.join("\n")
|
50
|
+
contents =<<-EOF
|
51
|
+
#{metatext}
|
52
|
+
|
53
|
+
#{heading}#{data[:content]}
|
54
|
+
EOF
|
55
|
+
FileUtils.mkdir_p(File.dirname(filename))
|
56
|
+
File.open(filename, 'w') { |file| file.write(contents) }
|
57
|
+
yield(filename) if block_given?
|
58
|
+
end
|
59
|
+
|
60
|
+
def heading
|
61
|
+
return '' unless data[:heading]
|
62
|
+
prefix = {
|
63
|
+
'haml' => "%div\n %h1",
|
64
|
+
'textile' => "<div>\nh1."
|
65
|
+
}.fetch(data[:ext], '# ')
|
66
|
+
"#{prefix} #{data[:heading]}\n\n"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class PageWriter < FileModelWriter
|
71
|
+
def model_class
|
72
|
+
Nesta::Page
|
73
|
+
end
|
74
|
+
|
75
|
+
def sequence_prefix
|
76
|
+
'page-'
|
77
|
+
end
|
78
|
+
|
79
|
+
def default_data
|
80
|
+
path = default_path
|
81
|
+
{ path: path, heading: heading_from_path(path) }
|
82
|
+
end
|
83
|
+
|
84
|
+
def heading_from_path(path)
|
85
|
+
File.basename(path).sub('-', ' ').capitalize
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
class ArticleWriter < PageWriter
|
90
|
+
def sequence_prefix
|
91
|
+
'articles/page-'
|
92
|
+
end
|
93
|
+
|
94
|
+
def default_data
|
95
|
+
path = default_path
|
96
|
+
{
|
97
|
+
path: path,
|
98
|
+
heading: heading_from_path(path),
|
99
|
+
content: 'Content goes here',
|
100
|
+
metadata: {
|
101
|
+
'date' => '29 December 2008'
|
102
|
+
}
|
103
|
+
}
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class CategoryWriter < PageWriter
|
108
|
+
def sequence_prefix
|
109
|
+
'categories/page-'
|
110
|
+
end
|
111
|
+
|
112
|
+
def default_data
|
113
|
+
path = default_path
|
114
|
+
{
|
115
|
+
path: path,
|
116
|
+
heading: heading_from_path(path),
|
117
|
+
content: 'Content goes here'
|
118
|
+
}
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
@@sequence = 0
|
123
|
+
def self.next_sequence_number
|
124
|
+
@@sequence += 1
|
125
|
+
end
|
126
|
+
|
127
|
+
def before_setup
|
128
|
+
# This is a minitest hook. We reset file sequence number at the
|
129
|
+
# start of each test so that we can automatically generate a unique
|
130
|
+
# path for each file we create within a test.
|
131
|
+
@@sequence = 0
|
132
|
+
end
|
133
|
+
|
134
|
+
def create(type, data = {}, &block)
|
135
|
+
file_writer = writer_class(type).new(type, data)
|
136
|
+
file_writer.write(&block)
|
137
|
+
file_writer.instantiate_model
|
138
|
+
end
|
139
|
+
|
140
|
+
def write_menu_item(indent, file, menu_item)
|
141
|
+
if menu_item.is_a?(Array)
|
142
|
+
indent.sub!(/^/, ' ')
|
143
|
+
menu_item.each { |path| write_menu_item(indent, file, path) }
|
144
|
+
indent.sub!(/^ /, '')
|
145
|
+
else
|
146
|
+
file.write("#{indent}#{menu_item}\n")
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def create_menu(menu_text)
|
151
|
+
file = filename(Nesta::Config.content_path, 'menu', :txt)
|
152
|
+
File.open(file, 'w') { |file| file.write(menu_text) }
|
153
|
+
end
|
154
|
+
|
155
|
+
def create_content_directories
|
156
|
+
FileUtils.mkdir_p(Nesta::Config.page_path)
|
157
|
+
FileUtils.mkdir_p(Nesta::Config.attachment_path)
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
def filename(directory, basename, extension = :mdown)
|
162
|
+
File.join(directory, "#{basename}.#{extension}")
|
163
|
+
end
|
164
|
+
|
165
|
+
def writer_class(type)
|
166
|
+
camelcased_type = type.to_s.gsub(/(?:^|_)(\w)/) { $1.upcase }
|
167
|
+
ModelFactory.const_get(camelcased_type + 'Writer')
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module TemporaryFiles
|
2
|
+
TEMP_DIR = File.expand_path('tmp', File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
def remove_temp_directory
|
5
|
+
if File.exist?(TemporaryFiles::TEMP_DIR)
|
6
|
+
FileUtils.rm_r(TemporaryFiles::TEMP_DIR)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def temp_path(base)
|
11
|
+
File.join(TemporaryFiles::TEMP_DIR, base)
|
12
|
+
end
|
13
|
+
|
14
|
+
def project_root
|
15
|
+
temp_path('mysite.com')
|
16
|
+
end
|
17
|
+
|
18
|
+
def project_path(path)
|
19
|
+
File.join(project_root, path)
|
20
|
+
end
|
21
|
+
|
22
|
+
def in_temporary_project(*args, &block)
|
23
|
+
FileUtils.mkdir_p(File.join(project_root, 'config'))
|
24
|
+
File.open(File.join(project_root, 'config', 'config.yml'), 'w').close
|
25
|
+
Dir.chdir(project_root) { yield }
|
26
|
+
ensure
|
27
|
+
remove_temp_directory
|
28
|
+
end
|
29
|
+
|
30
|
+
def assert_exists_in_project(path)
|
31
|
+
assert File.exist?(project_path(path)), "#{path} should exist"
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module TestConfiguration
|
2
|
+
include TemporaryFiles
|
3
|
+
|
4
|
+
def stub_config(config, &block)
|
5
|
+
Nesta::Config.stub(:yaml_exists?, true) do
|
6
|
+
Nesta::Config.stub(:yaml_conf, config) do
|
7
|
+
yield
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def temp_content
|
13
|
+
{ 'content' => temp_path('content') }
|
14
|
+
end
|
15
|
+
|
16
|
+
def with_temp_content_directory(&block)
|
17
|
+
stub_config(temp_content) { yield }
|
18
|
+
end
|
19
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
|
4
|
+
require 'minitest/reporters'
|
5
|
+
|
6
|
+
reporter_setting = ENV.fetch('REPORTER', 'progress')
|
7
|
+
camel_case = reporter_setting.split(/_/).map { |word| word.capitalize }.join('')
|
8
|
+
Minitest::Reporters.use! Minitest::Reporters.const_get("#{camel_case}Reporter").new
|
9
|
+
|
10
|
+
require File.expand_path('../lib/nesta/env', File.dirname(__FILE__))
|
11
|
+
require File.expand_path('../lib/nesta/app', File.dirname(__FILE__))
|
12
|
+
|
13
|
+
require_relative 'support/model_factory'
|
14
|
+
require_relative 'support/temporary_files'
|
15
|
+
require_relative 'support/test_configuration'
|
16
|
+
|
17
|
+
Nesta::App.environment = 'test'
|
18
|
+
|
19
|
+
class Minitest::Test
|
20
|
+
def with_app_root(path, &block)
|
21
|
+
original, Nesta::App.root = Nesta::App.root, path
|
22
|
+
yield
|
23
|
+
ensure
|
24
|
+
Nesta::App.root = original
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Nesta::Config do
|
4
|
+
include TestConfiguration
|
5
|
+
|
6
|
+
after do
|
7
|
+
ENV.keys.each { |variable| ENV.delete(variable) if variable =~ /NESTA_/ }
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'returns default value for "Read more"' do
|
11
|
+
assert_equal 'Continue reading', Nesta::Config.read_more
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'returns nil for author when not defined' do
|
15
|
+
assert_nil Nesta::Config.author
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'when settings defined in ENV' do
|
19
|
+
before do
|
20
|
+
@title = 'Title from ENV'
|
21
|
+
ENV['NESTA_TITLE'] = @title
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'falls back to config.yml' do
|
25
|
+
stub_config('subtitle' => 'Subtitle in YAML file') do
|
26
|
+
assert_equal 'Subtitle in YAML file', Nesta::Config.subtitle
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'overrides config.yml' do
|
31
|
+
stub_config('title' => 'Title in YAML file') do
|
32
|
+
assert_equal @title, Nesta::Config.title
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'knows how to cope with boolean values' do
|
37
|
+
Nesta::Config.settings << 'a_boolean'
|
38
|
+
begin
|
39
|
+
ENV['NESTA_A_BOOLEAN'] = 'true'
|
40
|
+
assert_equal true, Nesta::Config.a_boolean, 'should be true'
|
41
|
+
ENV['NESTA_A_BOOLEAN'] = 'false'
|
42
|
+
assert_equal false, Nesta::Config.a_boolean, 'should be false'
|
43
|
+
ensure
|
44
|
+
Nesta::Config.settings.pop
|
45
|
+
ENV.delete('NESTA_A_BOOLEAN')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should return configured value for "Read more"' do
|
50
|
+
ENV['NESTA_READ_MORE'] = 'Read on'
|
51
|
+
begin
|
52
|
+
assert_equal 'Read on', Nesta::Config.read_more
|
53
|
+
ensure
|
54
|
+
ENV.delete('NESTA_READ_MORE')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'sets author hash from ENV' do
|
59
|
+
name = 'Name from ENV'
|
60
|
+
uri = 'URI from ENV'
|
61
|
+
ENV['NESTA_AUTHOR__NAME'] = name
|
62
|
+
ENV['NESTA_AUTHOR__URI'] = uri
|
63
|
+
assert_equal name, Nesta::Config.author['name']
|
64
|
+
assert_equal uri, Nesta::Config.author['uri']
|
65
|
+
assert Nesta::Config.author['email'].nil?, 'should be nil'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe 'when settings only defined in config.yml' do
|
70
|
+
before do
|
71
|
+
@title = 'Title in YAML file'
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'reads configuration from YAML' do
|
75
|
+
stub_config('subtitle' => @title) do
|
76
|
+
assert_equal @title, Nesta::Config.subtitle
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'sets author hash from YAML' do
|
81
|
+
name = 'Name from YAML'
|
82
|
+
uri = 'URI from YAML'
|
83
|
+
stub_config('author' => { 'name' => name, 'uri' => uri }) do
|
84
|
+
assert_equal name, Nesta::Config.author['name']
|
85
|
+
assert_equal uri, Nesta::Config.author['uri']
|
86
|
+
assert Nesta::Config.author['email'].nil?, 'should be nil'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'overrides top level settings with environment specific settings' do
|
91
|
+
config = {
|
92
|
+
'content' => 'general/path',
|
93
|
+
'test' => { 'content' => 'rack_env_specific/path' }
|
94
|
+
}
|
95
|
+
stub_config(config) do
|
96
|
+
assert_equal 'rack_env_specific/path', Nesta::Config.content
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe 'Nesta::Config.fetch' do
|
102
|
+
it 'retrieves settings from environment' do
|
103
|
+
ENV['NESTA_MY_SETTING'] = 'value in ENV'
|
104
|
+
begin
|
105
|
+
assert_equal 'value in ENV', Nesta::Config.fetch('my_setting')
|
106
|
+
assert_equal 'value in ENV', Nesta::Config.fetch(:my_setting)
|
107
|
+
ensure
|
108
|
+
ENV.delete('NESTA_MY_SETTING')
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'retrieves settings from YAML' do
|
113
|
+
stub_config('my_setting' => 'value in YAML') do
|
114
|
+
assert_equal 'value in YAML', Nesta::Config.fetch('my_setting')
|
115
|
+
assert_equal 'value in YAML', Nesta::Config.fetch(:my_setting)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
it "throws NotDefined if a setting isn't defined" do
|
120
|
+
assert_raises(Nesta::Config::NotDefined) do
|
121
|
+
Nesta::Config.fetch('no such setting')
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'allows default values to be set' do
|
126
|
+
assert_equal 'default', Nesta::Config.fetch('no such setting', 'default')
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'copes with non-truthy boolean values' do
|
130
|
+
ENV['NESTA_SETTING'] = 'false'
|
131
|
+
begin
|
132
|
+
assert_equal false, Nesta::Config.fetch('setting')
|
133
|
+
ensure
|
134
|
+
ENV.delete('NESTA_SETTING')
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Nesta::FileModel do
|
4
|
+
include ModelFactory
|
5
|
+
include TestConfiguration
|
6
|
+
|
7
|
+
after do
|
8
|
+
Nesta::FileModel.purge_cache
|
9
|
+
remove_temp_directory
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'can find all files of this type' do
|
13
|
+
with_temp_content_directory do
|
14
|
+
model = create(:file_model)
|
15
|
+
assert_equal [model], Nesta::FileModel.find_all
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '.find_file_for_path' do
|
20
|
+
it 'returns filename for path' do
|
21
|
+
with_temp_content_directory do
|
22
|
+
model = create(:file_model)
|
23
|
+
filename = Nesta::FileModel.find_file_for_path(model.path)
|
24
|
+
assert_equal filename, model.filename
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'returns nil if file not found' do
|
29
|
+
with_temp_content_directory do
|
30
|
+
assert_nil Nesta::FileModel.find_file_for_path('foobar')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'can parse metadata at top of a file' do
|
36
|
+
with_temp_content_directory do
|
37
|
+
model = create(:file_model)
|
38
|
+
metadata = model.parse_metadata('My key: some value')
|
39
|
+
assert_equal 'some value', metadata['my key']
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "doesn't break loading pages with badly formatted metadata" do
|
44
|
+
with_temp_content_directory do
|
45
|
+
dodgy_metadata = "Key: value\nKey without value\nAnother key: value"
|
46
|
+
page = create(:page) do |path|
|
47
|
+
text = File.read(path)
|
48
|
+
File.open(path, 'w') do |file|
|
49
|
+
file.puts(dodgy_metadata)
|
50
|
+
file.write(text)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
Nesta::Page.find_by_path(page.path)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'invalidates cached models when files are modified' do
|
58
|
+
with_temp_content_directory do
|
59
|
+
create(:file_model, path: 'a-page', metadata: { 'Version' => '1' })
|
60
|
+
now = Time.now
|
61
|
+
File.stub(:mtime, now - 1) do
|
62
|
+
Nesta::FileModel.load('a-page')
|
63
|
+
end
|
64
|
+
create(:file_model, path: 'a-page', metadata: { 'Version' => '2' })
|
65
|
+
model = File.stub(:mtime, now) do
|
66
|
+
Nesta::FileModel.load('a-page')
|
67
|
+
end
|
68
|
+
assert_equal '2', model.metadata('version')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Nesta::Menu do
|
4
|
+
include ModelFactory
|
5
|
+
include TestConfiguration
|
6
|
+
|
7
|
+
def with_page(&block)
|
8
|
+
with_temp_content_directory do
|
9
|
+
page = create(:page)
|
10
|
+
create_menu(page.path)
|
11
|
+
yield(page)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def with_hierarchy_of_pages(&block)
|
16
|
+
with_temp_content_directory do
|
17
|
+
pages = (1..6).map { |i| create(:page) }
|
18
|
+
text = <<-EOF
|
19
|
+
#{pages[0].path}
|
20
|
+
#{pages[1].path}
|
21
|
+
#{pages[2].path}
|
22
|
+
#{pages[3].path}
|
23
|
+
"no-such-page"
|
24
|
+
"another-missing-page"
|
25
|
+
#{pages[4].path}
|
26
|
+
#{pages[5].path}
|
27
|
+
EOF
|
28
|
+
create_menu(text)
|
29
|
+
yield(pages)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
after do
|
34
|
+
remove_temp_directory
|
35
|
+
Nesta::FileModel.purge_cache
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'retrieves Page objects for the menu' do
|
39
|
+
with_page do |page|
|
40
|
+
assert_equal [page], Nesta::Menu.full_menu
|
41
|
+
assert_equal [page], Nesta::Menu.for_path('/')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "filters pages that don't exist out of the menu" do
|
46
|
+
with_temp_content_directory do
|
47
|
+
page = create(:page)
|
48
|
+
text = ['no-such-page', page.path].join("\n")
|
49
|
+
create_menu(text)
|
50
|
+
assert_equal [page], Nesta::Menu.top_level
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe 'nested sub menus' do
|
55
|
+
it 'returns top level menu items' do
|
56
|
+
with_hierarchy_of_pages do |pages|
|
57
|
+
assert_equal [pages[0], pages[4]], Nesta::Menu.top_level
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'returns full tree of menu items' do
|
62
|
+
with_hierarchy_of_pages do |pages|
|
63
|
+
page1, page2, page3, page4, page5, page6 = pages
|
64
|
+
expected = [page1, [page2, [page3, page4]], page5, [page6]]
|
65
|
+
assert_equal expected, Nesta::Menu.full_menu
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'returns part of the tree of menu items' do
|
70
|
+
with_hierarchy_of_pages do |pages|
|
71
|
+
page1, page2, page3, page4, page5, page6 = pages
|
72
|
+
assert_equal [page2, [page3, page4]], Nesta::Menu.for_path(page2.path)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'deems menu for path not in menu to be nil' do
|
77
|
+
with_hierarchy_of_pages do
|
78
|
+
assert_nil Nesta::Menu.for_path('wibble')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|