nesta 0.11.1 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +5 -5
  2. data/.gitmodules +6 -0
  3. data/.travis.yml +9 -4
  4. data/CHANGES +18 -2
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +70 -54
  7. data/LICENSE +1 -1
  8. data/RELEASING.md +5 -6
  9. data/Rakefile +20 -3
  10. data/lib/nesta/app.rb +4 -8
  11. data/lib/nesta/commands/command.rb +1 -2
  12. data/lib/nesta/commands/demo/content.rb +23 -5
  13. data/lib/nesta/commands/theme/install.rb +9 -7
  14. data/lib/nesta/helpers.rb +14 -0
  15. data/lib/nesta/models.rb +26 -22
  16. data/lib/nesta/navigation.rb +1 -1
  17. data/lib/nesta/version.rb +1 -1
  18. data/nesta.gemspec +10 -11
  19. data/templates/config/config.yml +1 -1
  20. data/{spec → test}/fixtures/nesta-plugin-test/Gemfile +0 -0
  21. data/{spec → test}/fixtures/nesta-plugin-test/Rakefile +0 -0
  22. data/{spec → test}/fixtures/nesta-plugin-test/lib/nesta-plugin-test.rb +0 -0
  23. data/{spec → test}/fixtures/nesta-plugin-test/lib/nesta-plugin-test/init.rb +0 -0
  24. data/{spec → test}/fixtures/nesta-plugin-test/lib/nesta-plugin-test/version.rb +0 -0
  25. data/{spec → test}/fixtures/nesta-plugin-test/nesta-plugin-test.gemspec +0 -0
  26. data/test/integration/atom_feed_test.rb +178 -0
  27. data/test/integration/commands/demo/content_test.rb +31 -0
  28. data/test/integration/commands/edit_test.rb +21 -0
  29. data/test/integration/commands/new_test.rb +120 -0
  30. data/test/integration/commands/plugin/create_test.rb +128 -0
  31. data/test/integration/commands/theme/create_test.rb +35 -0
  32. data/test/integration/commands/theme/enable_test.rb +22 -0
  33. data/test/integration/commands/theme/install_test.rb +62 -0
  34. data/test/integration/default_theme_test.rb +220 -0
  35. data/test/integration/overrides_test.rb +118 -0
  36. data/test/integration/route_handlers_test.rb +96 -0
  37. data/test/integration/sitemap_test.rb +85 -0
  38. data/test/integration_test_helper.rb +61 -0
  39. data/test/support/model_factory.rb +169 -0
  40. data/test/support/silence_commands_during_tests.rb +5 -0
  41. data/test/support/temporary_files.rb +33 -0
  42. data/test/support/test_configuration.rb +19 -0
  43. data/test/test_helper.rb +26 -0
  44. data/test/unit/commands_test.rb +23 -0
  45. data/test/unit/config_test.rb +138 -0
  46. data/test/unit/file_model_test.rb +71 -0
  47. data/test/unit/menu_test.rb +82 -0
  48. data/test/unit/page_test.rb +571 -0
  49. data/test/unit/path_test.rb +41 -0
  50. data/test/unit/plugin_test.rb +47 -0
  51. data/views/master.sass +1 -1
  52. metadata +81 -85
  53. data/smoke-test.sh +0 -107
  54. data/spec/atom_spec.rb +0 -141
  55. data/spec/commands/demo/content_spec.rb +0 -65
  56. data/spec/commands/edit_spec.rb +0 -27
  57. data/spec/commands/new_spec.rb +0 -88
  58. data/spec/commands/plugin/create_spec.rb +0 -97
  59. data/spec/commands/system_spec.rb +0 -25
  60. data/spec/commands/theme/create_spec.rb +0 -41
  61. data/spec/commands/theme/enable_spec.rb +0 -44
  62. data/spec/commands/theme/install_spec.rb +0 -56
  63. data/spec/config_spec.rb +0 -127
  64. data/spec/model_factory.rb +0 -92
  65. data/spec/models_spec.rb +0 -700
  66. data/spec/overrides_spec.rb +0 -132
  67. data/spec/page_spec.rb +0 -560
  68. data/spec/path_spec.rb +0 -28
  69. data/spec/plugin_spec.rb +0 -51
  70. data/spec/sitemap_spec.rb +0 -105
  71. data/spec/spec_helper.rb +0 -114
@@ -0,0 +1,35 @@
1
+ require 'test_helper'
2
+ require_relative '../../../../lib/nesta/commands'
3
+
4
+ describe 'nesta theme:create' do
5
+ include TemporaryFiles
6
+
7
+ def theme_path(path = '')
8
+ File.join('themes', 'theme-name', path)
9
+ end
10
+
11
+ before do
12
+ FileUtils.mkdir_p(project_root)
13
+ end
14
+
15
+ after do
16
+ remove_temp_directory
17
+ end
18
+
19
+ it 'creates default files in the theme directory' do
20
+ Dir.chdir(project_root) do
21
+ Nesta::Commands::Theme::Create.new('theme-name').execute
22
+ end
23
+ assert_exists_in_project theme_path('README.md')
24
+ assert_exists_in_project theme_path('app.rb')
25
+ end
26
+
27
+ it 'copies default view templates into views directory' do
28
+ Dir.chdir(project_root) do
29
+ Nesta::Commands::Theme::Create.new('theme-name').execute
30
+ end
31
+ %w(layout.haml page.haml master.sass).each do |template|
32
+ assert_exists_in_project theme_path("views/#{template}")
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,22 @@
1
+ require 'test_helper'
2
+ require_relative '../../../../lib/nesta/commands'
3
+
4
+ describe 'nesta theme:enable' do
5
+ include TemporaryFiles
6
+
7
+ before do
8
+ FileUtils.mkdir_p(File.join(project_root, 'config'))
9
+ File.open(File.join(project_root, 'config', 'config.yml'), 'w').close
10
+ end
11
+
12
+ after do
13
+ remove_temp_directory
14
+ end
15
+
16
+ it 'enables the theme' do
17
+ Dir.chdir(project_root) do
18
+ Nesta::Commands::Theme::Enable.new('theme-name').execute
19
+ assert_match /^theme: theme-name/, File.read('config/config.yml')
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,62 @@
1
+ require 'test_helper'
2
+ require_relative '../../../support/silence_commands_during_tests'
3
+ require_relative '../../../../lib/nesta/commands'
4
+
5
+ Nesta::Commands::Theme::Install.send(:include, SilenceCommandsDuringTests)
6
+
7
+ describe 'nesta theme:install' do
8
+ include TemporaryFiles
9
+
10
+ def theme_name
11
+ 'test'
12
+ end
13
+
14
+ def repo_url
15
+ "../../fixtures/nesta-theme-#{theme_name}.git"
16
+ end
17
+
18
+ def theme_dir
19
+ project_path("themes/#{theme_name}")
20
+ end
21
+
22
+ before do
23
+ FileUtils.mkdir_p(project_root)
24
+ end
25
+
26
+ after do
27
+ remove_temp_directory
28
+ end
29
+
30
+ it 'clones the repository' do
31
+ in_temporary_project do
32
+ Nesta::Commands::Theme::Install.new(repo_url).execute
33
+ assert File.directory?(theme_dir), 'theme not cloned'
34
+ end
35
+ end
36
+
37
+ it "removes the theme's .git directory" do
38
+ in_temporary_project do
39
+ Nesta::Commands::Theme::Install.new(repo_url).execute
40
+ refute File.exist?("#{theme_dir}/.git"), '.git folder found'
41
+ end
42
+ end
43
+
44
+ it 'enables the freshly installed theme' do
45
+ in_temporary_project do
46
+ Nesta::Commands::Theme::Install.new(repo_url).execute
47
+ assert_match /theme: #{theme_name}/, File.read('config/config.yml')
48
+ end
49
+ end
50
+
51
+ it 'determines name of theme from name of repository' do
52
+ url = 'git://foobar.com/path/to/nesta-theme-the-name.git'
53
+ command = Nesta::Commands::Theme::Install.new(url)
54
+ assert_equal 'the-name', command.theme_name
55
+ end
56
+
57
+ it "falls back to name of repo when theme name doesn't match correct format" do
58
+ url = 'git://foobar.com/path/to/mytheme.git'
59
+ command = Nesta::Commands::Theme::Install.new(url)
60
+ assert_equal 'mytheme', command.theme_name
61
+ end
62
+ end
@@ -0,0 +1,220 @@
1
+ require 'integration_test_helper'
2
+
3
+ describe 'Default theme' do
4
+ include Nesta::IntegrationTest
5
+
6
+ def in_categories(*categories)
7
+ { 'categories' => categories.map(&:path).join(', ') }
8
+ end
9
+
10
+ it 'includes description meta tag' do
11
+ with_temp_content_directory do
12
+ model = create(:page, metadata: { 'Description' => 'A good page' })
13
+ visit model.path
14
+ xpath = "//meta[@name='description'][@content='A good page']"
15
+ assert_has_xpath xpath, visible: false
16
+ end
17
+ end
18
+
19
+ it 'includes keywords meta tag' do
20
+ with_temp_content_directory do
21
+ model = create(:page, metadata: { 'Keywords' => 'good, content' })
22
+ visit model.path
23
+ xpath = "//meta[@name='keywords'][@content='good, content']"
24
+ assert_has_xpath xpath, visible: false
25
+ end
26
+ end
27
+
28
+ it "doesn't include Google Analytics JavaScript snippet by default" do
29
+ with_temp_content_directory do
30
+ visit '/'
31
+ assert_has_no_css 'script', text: 'google-analytics.com'
32
+ end
33
+ end
34
+
35
+ it 'includes Google Analytics JavaScript when configured' do
36
+ analytics_code = { 'google_analytics_code' => 'UA-1234' }
37
+ stub_config(temp_content.merge('test' => analytics_code)) do
38
+ visit '/'
39
+ assert_nil all('script').find { |s| s[:src].match /analytics\.js/ }
40
+ end
41
+ end
42
+
43
+ it 'displays site title' do
44
+ site_config = {
45
+ 'title' => 'My blog',
46
+ 'subtitle' => 'about stuff',
47
+ }
48
+ stub_config(temp_content.merge(site_config)) do
49
+ visit '/'
50
+ assert_has_css 'h1', text: 'My blog'
51
+ assert_has_css 'h2', text: 'about stuff'
52
+ end
53
+ end
54
+
55
+ describe 'menus' do
56
+ def create_pages_in_menu
57
+ pages
58
+ end
59
+
60
+ it "doesn't include menu markup if menu not configured" do
61
+ with_temp_content_directory do
62
+ visit '/'
63
+ assert_has_no_css 'ul.menu'
64
+ end
65
+ end
66
+
67
+ it 'only displays first two levels of menu items' do
68
+ with_temp_content_directory do
69
+ level1, level2, level3 = (0..2).map { create(:page) }
70
+ text = "%s\n %s\n %s\n" % [level1, level2, level3].map(&:abspath)
71
+ create_menu(text)
72
+ visit '/'
73
+ assert_has_css "ul.menu li a:contains('#{level1.link_text}')"
74
+ assert_has_css "ul.menu li ul li a:contains('#{level2.link_text}')"
75
+ assert_has_no_css "ul.menu a:contains('#{level3.link_text}')"
76
+ end
77
+ end
78
+
79
+ def create_page_and_menu
80
+ model = create(:page)
81
+ create_menu(model.path)
82
+ model
83
+ end
84
+
85
+ it "highlights current page's menu item" do
86
+ with_temp_content_directory do
87
+ model = create_page_and_menu
88
+ visit model.path
89
+ assert_has_css "ul.menu li[class='current']:contains('#{model.link_text}')"
90
+ end
91
+ end
92
+
93
+ it "highlights current page's menu item when app mounted at /prefix" do
94
+ Capybara.app = Rack::Builder.new do
95
+ map '/prefix' do
96
+ run Nesta::App.new
97
+ end
98
+ end
99
+
100
+ with_temp_content_directory do
101
+ model = create_page_and_menu
102
+ visit "/prefix/#{model.path}"
103
+ assert_has_css "ul.menu li[class='current']:contains('#{model.link_text}')"
104
+ end
105
+ end
106
+ end
107
+
108
+ it 'only displays read more link for summarised pages' do
109
+ with_temp_content_directory do
110
+ category = create(:category)
111
+ metadata = in_categories(category)
112
+ summarised = create(:page, metadata: metadata.merge('summary' => 'Summary'))
113
+ not_summarised = create(:page, metadata: metadata)
114
+ visit category.path
115
+ assert_has_css 'li:nth-child(1) p', text: summarised.read_more
116
+ assert_has_no_css 'li:nth-child(2) p', text: not_summarised.read_more
117
+ end
118
+ end
119
+
120
+ it 'displays page summaries or full content of unsummarised pages' do
121
+ with_temp_content_directory do
122
+ category = create(:category)
123
+ metadata = in_categories(category)
124
+ summarised = create(:page,
125
+ content: 'Summarised content',
126
+ metadata: metadata.merge(summary: 'Summary'))
127
+ not_summarised = create(:page,
128
+ content: 'Unsummarised content',
129
+ metadata: metadata)
130
+ visit category.path
131
+
132
+ # Page with a summary
133
+ assert_has_css 'li:nth-child(1) p', text: 'Summary'
134
+ assert_has_no_css 'li:nth-child(1) p', text: 'content'
135
+
136
+ # Page without a summary
137
+ assert_has_css 'li:nth-child(2) p', text: 'Unsummarised content'
138
+ assert_has_no_css 'li:nth-child(2) p', text: 'Summary'
139
+ end
140
+ end
141
+
142
+ it 'displays contents of page' do
143
+ with_temp_content_directory do
144
+ model = create(:page, content: 'Body of page')
145
+ visit model.path
146
+ assert_has_css 'p', text: 'Body of page'
147
+ end
148
+ end
149
+
150
+ describe 'category' do
151
+ it 'displays its "articles heading" above the articles' do
152
+ with_temp_content_directory do
153
+ category = create(:category, metadata: {
154
+ 'articles heading' => 'Articles on this topic'
155
+ })
156
+ create(:article, metadata: in_categories(category))
157
+ visit category.path
158
+ assert_has_css 'h1', text: 'Articles on this topic'
159
+ end
160
+ end
161
+
162
+ it 'links to articles in category using article title' do
163
+ with_temp_content_directory do
164
+ category = create(:category)
165
+ article = create(:article, metadata: in_categories(category))
166
+ visit category.path
167
+ link_text, href = article.link_text, article.abspath
168
+ assert_has_css "ol h1 a[href$='#{href}']", text: link_text
169
+ end
170
+ end
171
+ end
172
+
173
+ describe 'article' do
174
+ it 'displays the date' do
175
+ with_temp_content_directory do
176
+ article = create(:article)
177
+ visit article.path
178
+ assert_has_css "time[datetime='#{article.date}']"
179
+ end
180
+ end
181
+
182
+ it 'links to parent page in breadcrumb' do
183
+ with_temp_content_directory do
184
+ parent = create(:category)
185
+ article = create(:article, path: "#{parent.path}/child")
186
+ visit article.path
187
+ href, link_text = parent.abspath, parent.link_text
188
+ assert_has_css "nav.breadcrumb a[href='#{href}']", text: link_text
189
+ end
190
+ end
191
+
192
+ it 'links to its categories at end of article' do
193
+ with_temp_content_directory do
194
+ categories = [create(:category), create(:category)]
195
+ article = create(:article, metadata: in_categories(*categories))
196
+ visit article.path
197
+ categories.each do |category|
198
+ href, link_text = category.abspath, category.link_text
199
+ assert_has_css "p.meta a[href$='#{href}']", text: link_text
200
+ end
201
+ end
202
+ end
203
+
204
+ it 'displays comments from Disqus' do
205
+ stub_config(temp_content.merge('disqus_short_name' => 'mysite')) do
206
+ article = create(:article)
207
+ visit article.path
208
+ assert_has_css '#disqus_thread'
209
+ assert_has_css 'script[src*="mysite.disqus.com"]', visible: false
210
+ end
211
+ end
212
+
213
+ it "doesn't use Disqus if it's not configured" do
214
+ with_temp_content_directory do
215
+ visit create(:article).path
216
+ assert_has_no_css '#disqus_thread'
217
+ end
218
+ end
219
+ end
220
+ end
@@ -0,0 +1,118 @@
1
+ require 'integration_test_helper'
2
+
3
+ describe 'Overriding files in gem and themes' do
4
+ include Nesta::IntegrationTest
5
+
6
+ def in_nesta_project(config = {}, &block)
7
+ app_root = temp_path('root')
8
+ content_config = { 'content' => File.join(app_root, 'content') }
9
+ stub_config(content_config.merge(config)) do
10
+ with_app_root(app_root) do
11
+ yield
12
+ end
13
+ end
14
+ ensure
15
+ remove_temp_directory
16
+ end
17
+
18
+ def theme_name
19
+ 'my-theme'
20
+ end
21
+
22
+ def create_fixture(type, name, content)
23
+ base_path = {
24
+ local: Nesta::Path.local,
25
+ theme: Nesta::Path.themes(theme_name)
26
+ }[type]
27
+ path = File.join(base_path, name)
28
+ FileUtils.mkdir_p(File.dirname(path))
29
+ open(path, 'w') { |file| file.write(content) }
30
+ end
31
+
32
+ def create_app_file(type)
33
+ create_fixture(type, 'app.rb', "FROM_#{type.to_s.upcase} = true")
34
+ end
35
+
36
+ describe 'app.rb' do
37
+ it 'loads app.rb from configured theme' do
38
+ in_nesta_project('theme' => theme_name) do
39
+ create_app_file(:theme)
40
+ Nesta::Overrides.load_theme_app
41
+ assert Object.const_get(:FROM_THEME), 'should load app.rb in theme'
42
+ end
43
+ end
44
+
45
+ it 'loads both local and theme app.rb files' do
46
+ in_nesta_project('theme' => theme_name) do
47
+ create_app_file(:local)
48
+ Nesta::Overrides.load_local_app
49
+ create_app_file(:theme)
50
+ Nesta::Overrides.load_theme_app
51
+ assert Object.const_get(:FROM_THEME), 'should load app.rb in theme'
52
+ assert Object.const_get(:FROM_LOCAL), 'should load local app.rb'
53
+ end
54
+ end
55
+ end
56
+
57
+ def create_view(type, name, content)
58
+ create_fixture(type, File.join('views', name), content)
59
+ end
60
+
61
+ describe 'rendering stylesheets' do
62
+ it 'renders Sass stylesheets' do
63
+ in_nesta_project do
64
+ create_view(:local, 'master.sass', "body\n width: 10px * 2")
65
+ visit '/css/master.css'
66
+ assert_match /width: 20px;/, body, 'should match /width: 20px;/'
67
+ end
68
+ end
69
+
70
+ it 'renders SCSS stylesheets' do
71
+ in_nesta_project do
72
+ create_view(:local, 'master.scss', "body {\n width: 10px * 2;\n}")
73
+ visit '/css/master.css'
74
+ assert_match /width: 20px;/, body, 'should match /width: 20px;/'
75
+ end
76
+ end
77
+
78
+ it 'renders stylesheet in the the gem if no others found' do
79
+ in_nesta_project do
80
+ visit '/css/master.css'
81
+ assert_equal 200, page.status_code
82
+ end
83
+ end
84
+ end
85
+
86
+ def create_haml(type, name, content)
87
+ create_view(type, 'layout.haml', '= yield')
88
+ create_view(type, name, content)
89
+ end
90
+
91
+ describe 'rendering Haml' do
92
+ it 'uses local template in place of default' do
93
+ in_nesta_project do
94
+ create_haml(:local, 'page.haml', '%p Local template')
95
+ visit create(:category).abspath
96
+ assert_has_xpath '//p', text: 'Local template'
97
+ end
98
+ end
99
+
100
+ it 'uses theme template in place of default' do
101
+ in_nesta_project('theme' => theme_name) do
102
+ create_haml(:theme, 'page.haml', '%p Theme template')
103
+ visit create(:category).abspath
104
+ assert_has_xpath '//p', text: 'Theme template'
105
+ end
106
+ end
107
+
108
+ it 'prioritise local templates over theme templates' do
109
+ in_nesta_project('theme' => theme_name) do
110
+ create_haml(:local, 'page.haml', '%p Local template')
111
+ create_haml(:theme, 'page.haml', '%p Theme template')
112
+ visit create(:category).abspath
113
+ assert_has_xpath '//p', text: 'Local template'
114
+ assert_has_no_xpath '//p', text: 'Theme template'
115
+ end
116
+ end
117
+ end
118
+ end