nesta 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/.gitignore +13 -0
  2. data/Gemfile +6 -0
  3. data/Gemfile.lock +58 -0
  4. data/LICENSE +19 -0
  5. data/README.md +45 -0
  6. data/Rakefile +12 -0
  7. data/bin/nesta +67 -0
  8. data/config.ru +9 -0
  9. data/config/config.yml.sample +73 -0
  10. data/config/deploy.rb.sample +62 -0
  11. data/lib/nesta/app.rb +199 -0
  12. data/lib/nesta/cache.rb +139 -0
  13. data/lib/nesta/commands.rb +135 -0
  14. data/lib/nesta/config.rb +87 -0
  15. data/lib/nesta/models.rb +313 -0
  16. data/lib/nesta/nesta.rb +0 -0
  17. data/lib/nesta/overrides.rb +59 -0
  18. data/lib/nesta/path.rb +11 -0
  19. data/lib/nesta/plugins.rb +15 -0
  20. data/lib/nesta/version.rb +3 -0
  21. data/nesta.gemspec +49 -0
  22. data/scripts/import-from-mephisto +207 -0
  23. data/spec/atom_spec.rb +138 -0
  24. data/spec/commands_spec.rb +220 -0
  25. data/spec/config_spec.rb +69 -0
  26. data/spec/model_factory.rb +94 -0
  27. data/spec/models_spec.rb +445 -0
  28. data/spec/overrides_spec.rb +113 -0
  29. data/spec/page_spec.rb +428 -0
  30. data/spec/path_spec.rb +28 -0
  31. data/spec/sitemap_spec.rb +102 -0
  32. data/spec/spec.opts +1 -0
  33. data/spec/spec_helper.rb +72 -0
  34. data/templates/Gemfile +8 -0
  35. data/templates/Rakefile +35 -0
  36. data/templates/config.ru +9 -0
  37. data/templates/config/config.yml +73 -0
  38. data/templates/config/deploy.rb +47 -0
  39. data/views/analytics.haml +12 -0
  40. data/views/atom.builder +28 -0
  41. data/views/categories.haml +3 -0
  42. data/views/comments.haml +8 -0
  43. data/views/error.haml +13 -0
  44. data/views/feed.haml +3 -0
  45. data/views/index.haml +5 -0
  46. data/views/layout.haml +27 -0
  47. data/views/master.sass +246 -0
  48. data/views/not_found.haml +13 -0
  49. data/views/page.haml +29 -0
  50. data/views/sidebar.haml +3 -0
  51. data/views/sitemap.builder +15 -0
  52. data/views/summaries.haml +14 -0
  53. metadata +302 -0
@@ -0,0 +1,113 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+ require File.expand_path('model_factory', File.dirname(__FILE__))
3
+
4
+ describe "Rendering" do
5
+ include ConfigSpecHelper
6
+ include ModelFactory
7
+ include RequestSpecHelper
8
+
9
+ def create_fixture(type, name, content)
10
+ base_path = {
11
+ :local => Nesta::Path.local,
12
+ :theme => Nesta::Path.themes(@theme)
13
+ }[type]
14
+ path = File.join(base_path, name)
15
+ @fixtures << path
16
+ FileUtils.mkdir_p(File.dirname(path))
17
+ open(path, 'w') { |file| file.write(content) }
18
+ end
19
+
20
+ def create_template(type, name, content)
21
+ create_fixture(type, File.join('views', name), content)
22
+ end
23
+
24
+ def create_app_file(type)
25
+ create_fixture(type, 'app.rb', "DEFINED_IN_#{type.to_s.upcase}_FILE = true")
26
+ end
27
+
28
+ before(:each) do
29
+ @app_root = Nesta::App.root
30
+ Nesta::App.root = File.expand_path('fixtures/tmp', File.dirname(__FILE__))
31
+ @theme = 'my-theme'
32
+ @fixtures = []
33
+ stub_configuration
34
+ end
35
+
36
+ after(:each) do
37
+ @fixtures.each { |path| FileUtils.rm(path) if File.exist?(path) }
38
+ Nesta::App.root = @app_root
39
+ end
40
+
41
+ describe "when local files exist" do
42
+ before(:each) do
43
+ create_template(:local, 'page.haml', '%p Local template')
44
+ end
45
+
46
+ it "should use local application files" do
47
+ create_app_file(:local)
48
+ Nesta::Overrides.load_local_app
49
+ Object.const_get(:DEFINED_IN_LOCAL_FILE).should be_true
50
+ end
51
+
52
+ it "should use local template in place of default" do
53
+ get create_category.abspath
54
+ body.should have_tag("p", "Local template")
55
+ end
56
+ end
57
+
58
+ describe "when theme installed" do
59
+ before(:each) do
60
+ create_template(:theme, 'page.haml', '%p Theme template')
61
+ end
62
+
63
+ it "should not require theme application file automatically" do
64
+ create_app_file(:theme)
65
+ lambda {
66
+ Object.const_get(:DEFINED_IN_THEME_FILE)
67
+ }.should raise_error(NameError)
68
+ end
69
+
70
+ it "should not use theme templates automatically" do
71
+ get create_category.abspath
72
+ body.should_not have_tag("p", "Theme template")
73
+ end
74
+
75
+ describe "and configured" do
76
+ before(:each) do
77
+ stub_config_key("theme", @theme)
78
+ end
79
+
80
+ it "should require theme application file" do
81
+ create_app_file(:theme)
82
+ Nesta::Overrides.load_theme_app
83
+ Object.const_get(:DEFINED_IN_THEME_FILE).should be_true
84
+ end
85
+
86
+ it "should use theme's template in place of default" do
87
+ get create_category.abspath
88
+ body.should have_tag("p", "Theme template")
89
+ end
90
+
91
+ context "and local files exist" do
92
+ before(:each) do
93
+ create_template(:local, "page.haml", "%p Local template")
94
+ end
95
+
96
+ it "should require local and theme application files" do
97
+ create_app_file(:local)
98
+ create_app_file(:theme)
99
+ Nesta::Overrides.load_theme_app
100
+ Nesta::Overrides.load_local_app
101
+ Object.const_get(:DEFINED_IN_LOCAL_FILE).should be_true
102
+ Object.const_get(:DEFINED_IN_THEME_FILE).should be_true
103
+ end
104
+
105
+ it "should use local template" do
106
+ get create_category.abspath
107
+ body.should_not have_tag("p", "Theme template")
108
+ body.should have_tag("p", "Local template")
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
data/spec/page_spec.rb ADDED
@@ -0,0 +1,428 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+ require File.expand_path('model_factory', File.dirname(__FILE__))
3
+
4
+ describe "page with keyword and description", :shared => true do
5
+ it "should set the keywords meta tag" do
6
+ do_get
7
+ body.should have_tag("meta[@name=keywords][@content='#{@keywords}']")
8
+ end
9
+
10
+ it "should set description meta tag" do
11
+ do_get
12
+ body.should have_tag("meta[@name=description][@content='#{@description}']")
13
+ end
14
+ end
15
+
16
+ describe "page that can display menus", :shared => true do
17
+ it "should not display menu by default" do
18
+ do_get
19
+ body.should_not have_tag("#sidebar ul.menu")
20
+ end
21
+
22
+ describe "and simple menu configured" do
23
+ before(:each) do
24
+ create_menu(@category.path)
25
+ end
26
+
27
+ it "should link to top level menu items" do
28
+ do_get
29
+ body.should have_tag(
30
+ "ul.menu a[@href=#{@category.abspath}]", Regexp.new(@category.heading))
31
+ end
32
+ end
33
+
34
+ describe "and nested menu configured" do
35
+ before(:each) do
36
+ @level2 = create_category(:path => "level-2", :heading => "Level 2")
37
+ @level3 = create_category(:path => "level-3", :heading => "Level 3")
38
+ text = <<-EOF
39
+ #{@category.abspath}
40
+ #{@level2.abspath}
41
+ #{@level3.abspath}
42
+ EOF
43
+ create_menu(text)
44
+ end
45
+
46
+ it "should display first level of nested sub menus" do
47
+ do_get
48
+ body.should have_tag("ul.menu li ul li a", Regexp.new(@level2.heading))
49
+ end
50
+
51
+ it "should not display nested menus to arbitrary depth" do
52
+ do_get
53
+ body.should_not have_tag("ul.menu li ul li ul")
54
+ end
55
+ end
56
+ end
57
+
58
+ describe "The layout" do
59
+ include ConfigSpecHelper
60
+ include ModelFactory
61
+ include RequestSpecHelper
62
+
63
+ it "should not include GA JavaScript by default" do
64
+ stub_configuration
65
+ get "/"
66
+ body.should_not have_tag("script", /'_setAccount', 'UA-1234'/)
67
+ end
68
+
69
+ it "should include GA JavaScript if configured" do
70
+ stub_config_key('google_analytics_code', 'UA-1234', :rack_env => true)
71
+ stub_configuration
72
+ get '/'
73
+ body.should have_tag('script', /'_setAccount', 'UA-1234'/)
74
+ end
75
+ end
76
+
77
+ describe "The home page" do
78
+ include ConfigSpecHelper
79
+ include ModelFactory
80
+ include RequestSpecHelper
81
+
82
+ before(:each) do
83
+ stub_configuration
84
+ create_category
85
+ end
86
+
87
+ after(:each) do
88
+ remove_fixtures
89
+ Nesta::FileModel.purge_cache
90
+ end
91
+
92
+ def do_get
93
+ get "/"
94
+ end
95
+
96
+ describe "when categories exist" do
97
+ before(:each) do
98
+ @category = create_category
99
+ end
100
+
101
+ it_should_behave_like "page that can display menus"
102
+ end
103
+
104
+ it "should render successfully" do
105
+ do_get
106
+ last_response.should be_ok
107
+ end
108
+
109
+ it "should display title and subtitle in title tag" do
110
+ do_get
111
+ body.should have_tag("title", "My blog - about stuff")
112
+ end
113
+
114
+ it "should display site title in h1 tag" do
115
+ do_get
116
+ body.should have_tag('#header p.title', /My blog/)
117
+ end
118
+
119
+ it "should display site subtitle in h1 tag" do
120
+ do_get
121
+ body.should have_tag('#header p.subtitle', /about stuff/)
122
+ end
123
+
124
+ it "should set description meta tag" do
125
+ do_get
126
+ body.should have_tag("meta[@name=description][@content='great web site']")
127
+ end
128
+
129
+ it "should set keywords meta tag" do
130
+ do_get
131
+ body.should have_tag("meta[@name=keywords][@content='home, page']")
132
+ end
133
+
134
+ describe "when articles have no summary" do
135
+ before(:each) do
136
+ create_article
137
+ do_get
138
+ end
139
+
140
+ it "should display full content of article" do
141
+ body.should have_tag("p", "Content goes here")
142
+ end
143
+
144
+ it "should not display read more link" do
145
+ body.should_not have_tag("a", /continue/i)
146
+ end
147
+ end
148
+
149
+ describe "when articles have metadata" do
150
+ before(:each) do
151
+ @summary = 'Multiline\n\nsummary'
152
+ @read_more = "Continue at your leisure"
153
+ @article = create_article(:metadata => {
154
+ "summary" => @summary,
155
+ "read more" => @read_more
156
+ })
157
+ do_get
158
+ end
159
+
160
+ it "should display link to article in h2 tag" do
161
+ body.should have_tag(
162
+ "h2 a[@href=#{@article.abspath}]", /^\s*#{@article.heading}$/)
163
+ end
164
+
165
+ it "should display article summary if available" do
166
+ body.should have_tag("p", @summary.split('\n\n').first)
167
+ end
168
+
169
+ it "should display read more link" do
170
+ body.should have_tag("a[@href=#{@article.abspath}]", @read_more)
171
+ end
172
+ end
173
+ end
174
+
175
+ describe "An article" do
176
+ include ConfigSpecHelper
177
+ include ModelFactory
178
+ include RequestSpecHelper
179
+
180
+ before(:each) do
181
+ stub_configuration
182
+ @date = "07 September 2009"
183
+ @keywords = "things, stuff"
184
+ @description = "Page about stuff"
185
+ @summary = 'Multiline\n\nsummary'
186
+ @article = create_article(:metadata => {
187
+ "date" => @date.gsub("September", "Sep"),
188
+ "description" => @description,
189
+ "keywords" => @keywords,
190
+ "summary" => @summary,
191
+ })
192
+ end
193
+
194
+ after(:each) do
195
+ remove_fixtures
196
+ Nesta::FileModel.purge_cache
197
+ end
198
+
199
+ def do_get
200
+ get @article.abspath
201
+ end
202
+
203
+ it_should_behave_like "page with keyword and description"
204
+
205
+ describe "when categories exist" do
206
+ before(:each) do
207
+ @category = create_category
208
+ end
209
+
210
+ it_should_behave_like "page that can display menus"
211
+ end
212
+
213
+ it "should render successfully" do
214
+ do_get
215
+ last_response.should be_ok
216
+ end
217
+
218
+ it "should display the heading" do
219
+ do_get
220
+ body.should have_tag("h1", "My article")
221
+ end
222
+
223
+ it "should not display category links" do
224
+ do_get
225
+ body.should_not have_tag("div.breadcrumb div.categories", /filed in/)
226
+ end
227
+
228
+ it "should display the date" do
229
+ do_get
230
+ body.should have_tag("div.date", @date)
231
+ end
232
+
233
+ it "should display the content" do
234
+ do_get
235
+ body.should have_tag("p", "Content goes here")
236
+ end
237
+
238
+ describe "that is assigned to categories" do
239
+ before(:each) do
240
+ create_category(:heading => "Apple", :path => "the-apple")
241
+ @category = create_category(:heading => "Banana", :path => "banana")
242
+ @article = create_article(
243
+ :path => "#{@category.path}/article",
244
+ :metadata => { "categories" => "banana, the-apple" }
245
+ )
246
+ end
247
+
248
+ it "should render successfully" do
249
+ do_get
250
+ last_response.should be_ok
251
+ end
252
+
253
+ it "should link to each category" do
254
+ do_get
255
+ body.should have_tag("div.categories", /Categories/)
256
+ body.should have_tag("div.categories") do |categories|
257
+ categories.should have_tag("a[@href=/banana]", "Banana")
258
+ categories.should have_tag("a[@href=/the-apple]", "Apple")
259
+ end
260
+ end
261
+
262
+ it "should link to a category in breadcrumb" do
263
+ do_get
264
+ body.should have_tag(
265
+ "div.breadcrumb/a[@href=#{@category.abspath}]", @category.heading)
266
+ end
267
+
268
+ it "should contain category name in page title" do
269
+ do_get
270
+ body.should_not have_tag("title", /My blog/)
271
+ body.should have_tag("title", /- #{@category.heading}$/)
272
+ end
273
+ end
274
+ end
275
+
276
+ describe "A page" do
277
+ include ConfigSpecHelper
278
+ include ModelFactory
279
+ include RequestSpecHelper
280
+
281
+ before(:each) do
282
+ stub_configuration
283
+ end
284
+
285
+ after(:each) do
286
+ remove_fixtures
287
+ Nesta::FileModel.purge_cache
288
+ end
289
+
290
+ def do_get
291
+ get @category.abspath
292
+ end
293
+
294
+ describe "that doesn't exist" do
295
+ it "should render the 404 page" do
296
+ get "/no-such-page"
297
+ last_response.should_not be_ok
298
+ end
299
+ end
300
+
301
+ describe "that has meta data" do
302
+ before(:each) do
303
+ @content = "Page content"
304
+ @description = "Page about stuff"
305
+ @keywords = "things, stuff"
306
+ @category = create_category(
307
+ :content => "# My category\n\n#{@content}",
308
+ :metadata => { "description" => @description, "keywords" => @keywords }
309
+ )
310
+ end
311
+
312
+ it_should_behave_like "page with keyword and description"
313
+ it_should_behave_like "page that can display menus"
314
+
315
+ it "should render successfully" do
316
+ do_get
317
+ last_response.should be_ok
318
+ end
319
+
320
+ it "should display the heading" do
321
+ do_get
322
+ body.should have_tag("h1", @category.heading)
323
+ end
324
+
325
+ it "should display the content" do
326
+ do_get
327
+ body.should have_tag("p", @content)
328
+ end
329
+
330
+ describe "with associated articles" do
331
+ before(:each) do
332
+ @article = create_article(
333
+ :path => "another-page",
334
+ :heading => "Categorised",
335
+ :metadata => { :categories => @category.path },
336
+ :content => "Article content"
337
+ )
338
+ @article2 = create_article(
339
+ :path => "second-article", :heading => "Second article")
340
+ end
341
+
342
+ it "should display links to articles" do
343
+ do_get
344
+ body.should have_tag(
345
+ "h3 a[@href='#{@article.abspath}']", /^\s*#{@article.heading}$/)
346
+ body.should_not have_tag("h3", @article2.heading)
347
+ end
348
+ end
349
+
350
+ it "should not include Disqus comments by default" do
351
+ do_get
352
+ body.should_not have_tag('#disqus_thread')
353
+ end
354
+ end
355
+
356
+ describe "that is configured to show Disqus comments" do
357
+ before(:each) do
358
+ stub_config_key("disqus_short_name", "mysite")
359
+ @category = create_category
360
+ end
361
+
362
+ it "should display Disqus comments" do
363
+ do_get
364
+ body.should have_tag('#disqus_thread')
365
+ body.should have_tag('script[@src*="mysite/embed.js"]')
366
+ end
367
+ end
368
+ end
369
+
370
+ describe "A Haml page" do
371
+ include ConfigSpecHelper
372
+ include ModelFactory
373
+ include RequestSpecHelper
374
+
375
+ before(:each) do
376
+ stub_configuration
377
+ end
378
+
379
+ after(:each) do
380
+ remove_fixtures
381
+ Nesta::FileModel.purge_cache
382
+ end
383
+
384
+ it "should be able to access helper methods" do
385
+ create_page(
386
+ :path => "a-page",
387
+ :ext => :haml,
388
+ :content => "%div= format_date(Date.new(2010, 11, 23))"
389
+ )
390
+ get "/a-page"
391
+ body.should have_tag("div", "23 November 2010")
392
+ end
393
+ end
394
+
395
+ describe "attachments" do
396
+ include ConfigSpecHelper
397
+ include ModelFactory
398
+ include RequestSpecHelper
399
+
400
+ def create_attachment
401
+ stub_configuration
402
+ create_content_directories
403
+ path = File.join(Nesta::Config.attachment_path, "test.txt")
404
+ File.open(path, "w") { |file| file.write("I'm a test attachment") }
405
+ end
406
+
407
+ before(:each) do
408
+ create_attachment
409
+ get "/attachments/test.txt"
410
+ end
411
+
412
+ after(:each) do
413
+ remove_fixtures
414
+ Nesta::FileModel.purge_cache
415
+ end
416
+
417
+ it "should be served successfully" do
418
+ last_response.should be_ok
419
+ end
420
+
421
+ it "should be sent to the client" do
422
+ body.should include("I'm a test attachment")
423
+ end
424
+
425
+ it "should set the appropriate MIME type" do
426
+ last_response.headers["Content-Type"].should =~ Regexp.new("^text/plain")
427
+ end
428
+ end