landable 1.7.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 +7 -0
- data/.gitignore +13 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +15 -0
- data/MIT-LICENSE +20 -0
- data/README.md +56 -0
- data/Rakefile +22 -0
- data/app/controllers/concerns/landable/variables_concern.rb +38 -0
- data/app/controllers/landable/api/access_tokens_controller.rb +48 -0
- data/app/controllers/landable/api/assets_controller.rb +55 -0
- data/app/controllers/landable/api/categories_controller.rb +13 -0
- data/app/controllers/landable/api/directories_controller.rb +19 -0
- data/app/controllers/landable/api/page_revisions_controller.rb +38 -0
- data/app/controllers/landable/api/pages_controller.rb +96 -0
- data/app/controllers/landable/api/templates_controller.rb +33 -0
- data/app/controllers/landable/api/themes_controller.rb +57 -0
- data/app/controllers/landable/api_controller.rb +75 -0
- data/app/controllers/landable/application_controller.rb +4 -0
- data/app/controllers/landable/public/pages_controller.rb +25 -0
- data/app/controllers/landable/public/preview/page_revisions_controller.rb +16 -0
- data/app/controllers/landable/public/preview/pages_controller.rb +16 -0
- data/app/controllers/landable/public/sitemap_controller.rb +18 -0
- data/app/decorators/landable/null_page_decorator.rb +26 -0
- data/app/decorators/landable/page_decorator.rb +40 -0
- data/app/helpers/landable/application_helper.rb +13 -0
- data/app/helpers/landable/pages_helper.rb +20 -0
- data/app/models/concerns/landable/has_assets.rb +74 -0
- data/app/models/concerns/landable/table_name.rb +12 -0
- data/app/models/concerns/landable/traffic/table_name.rb +14 -0
- data/app/models/landable/access_token.rb +20 -0
- data/app/models/landable/asset.rb +63 -0
- data/app/models/landable/asset_search_engine.rb +20 -0
- data/app/models/landable/author.rb +12 -0
- data/app/models/landable/category.rb +27 -0
- data/app/models/landable/directory.rb +23 -0
- data/app/models/landable/page.rb +259 -0
- data/app/models/landable/page_revision.rb +74 -0
- data/app/models/landable/page_search_engine.rb +20 -0
- data/app/models/landable/search_engine.rb +39 -0
- data/app/models/landable/template.rb +24 -0
- data/app/models/landable/theme.rb +20 -0
- data/app/models/landable/traffic/access.rb +11 -0
- data/app/models/landable/traffic/ad_group.rb +11 -0
- data/app/models/landable/traffic/ad_type.rb +11 -0
- data/app/models/landable/traffic/attribution.rb +38 -0
- data/app/models/landable/traffic/bid_match_type.rb +11 -0
- data/app/models/landable/traffic/browser.rb +11 -0
- data/app/models/landable/traffic/campaign.rb +11 -0
- data/app/models/landable/traffic/city.rb +11 -0
- data/app/models/landable/traffic/content.rb +11 -0
- data/app/models/landable/traffic/cookie.rb +16 -0
- data/app/models/landable/traffic/country.rb +11 -0
- data/app/models/landable/traffic/creative.rb +11 -0
- data/app/models/landable/traffic/device.rb +11 -0
- data/app/models/landable/traffic/device_type.rb +11 -0
- data/app/models/landable/traffic/domain.rb +12 -0
- data/app/models/landable/traffic/event.rb +12 -0
- data/app/models/landable/traffic/event_type.rb +11 -0
- data/app/models/landable/traffic/experiment.rb +11 -0
- data/app/models/landable/traffic/http_method.rb +11 -0
- data/app/models/landable/traffic/ip_address.rb +11 -0
- data/app/models/landable/traffic/ip_lookup.rb +12 -0
- data/app/models/landable/traffic/keyword.rb +11 -0
- data/app/models/landable/traffic/location.rb +11 -0
- data/app/models/landable/traffic/match_type.rb +11 -0
- data/app/models/landable/traffic/medium.rb +11 -0
- data/app/models/landable/traffic/mime_type.rb +11 -0
- data/app/models/landable/traffic/network.rb +11 -0
- data/app/models/landable/traffic/owner.rb +10 -0
- data/app/models/landable/traffic/ownership.rb +10 -0
- data/app/models/landable/traffic/page_view.rb +24 -0
- data/app/models/landable/traffic/path.rb +13 -0
- data/app/models/landable/traffic/placement.rb +11 -0
- data/app/models/landable/traffic/platform.rb +11 -0
- data/app/models/landable/traffic/position.rb +11 -0
- data/app/models/landable/traffic/query_string.rb +12 -0
- data/app/models/landable/traffic/referer.rb +11 -0
- data/app/models/landable/traffic/region.rb +11 -0
- data/app/models/landable/traffic/search_term.rb +11 -0
- data/app/models/landable/traffic/source.rb +11 -0
- data/app/models/landable/traffic/target.rb +11 -0
- data/app/models/landable/traffic/user_agent.rb +28 -0
- data/app/models/landable/traffic/user_agent_type.rb +11 -0
- data/app/models/landable/traffic/visit.rb +15 -0
- data/app/models/landable/traffic/visitor.rb +13 -0
- data/app/responders/landable/api_responder.rb +76 -0
- data/app/responders/landable/page_render_responder.rb +15 -0
- data/app/serializers/landable/access_token_serializer.rb +6 -0
- data/app/serializers/landable/asset_serializer.rb +14 -0
- data/app/serializers/landable/author_serializer.rb +5 -0
- data/app/serializers/landable/category_serializer.rb +5 -0
- data/app/serializers/landable/directory_serializer.rb +8 -0
- data/app/serializers/landable/page_revision_serializer.rb +15 -0
- data/app/serializers/landable/page_serializer.rb +31 -0
- data/app/serializers/landable/template_serializer.rb +5 -0
- data/app/serializers/landable/theme_serializer.rb +7 -0
- data/app/services/landable/authentication_service.rb +44 -0
- data/app/services/landable/registration_service.rb +13 -0
- data/app/services/landable/render_service.rb +86 -0
- data/app/services/landable/tidy_service.rb +155 -0
- data/app/uploaders/landable/asset_uploader.rb +9 -0
- data/app/validators/path_validator.rb +12 -0
- data/app/validators/url_validator.rb +13 -0
- data/app/views/templates/preview.liquid +122 -0
- data/bin/rails +8 -0
- data/bin/redb +7 -0
- data/config.ru +7 -0
- data/config/cucumber.yml +5 -0
- data/config/routes.rb +62 -0
- data/db/migrate/20130510221424_create_landable_schema.rb +338 -0
- data/db/migrate/20130909182713_landable_pages__add_updated_by.rb +11 -0
- data/db/migrate/20130909182715_landable_page_revisions__break_out_snapshot.rb +72 -0
- data/db/migrate/20130909191153_landable_pages__add_lock_version.rb +5 -0
- data/db/migrate/20131002220041_file_based_themes.rb +12 -0
- data/db/migrate/20131008164204_create_head_tag_on_page.rb +19 -0
- data/db/migrate/20131008193544_drop_status_codes_model.rb +44 -0
- data/db/migrate/20131028145652_add_traffic_schema.rb +276 -0
- data/db/migrate/20131101213623_add_dnt_column_to_visits.rb +7 -0
- data/db/migrate/20131104224120_add_meta_on_events.rb +7 -0
- data/db/migrate/20131106185946_add_index_on_page_revisions_path.rb +6 -0
- data/db/migrate/20131106193021_page_revisisons__path_status_code_index.rb +9 -0
- data/db/migrate/20131108212501_traffic_owner_ids_are_serials.rb +20 -0
- data/db/migrate/20131121150902_add_attribution_id_to_unique_index.rb +10 -0
- data/db/migrate/20131216214027_drop_browser_screenshot_tables.rb +6 -0
- data/db/migrate/20140128170659_file_backed_templates.rb +8 -0
- data/db/migrate/20140205193757_fix_status_codes.rb +24 -0
- data/db/migrate/20140206211322_add_response_time_to_traffic_page_views.rb +7 -0
- data/db/migrate/20140220170324_add_slug_to_categories.rb +14 -0
- data/db/migrate/20140220174630_add_abstract_and_hero_asset_to_pages_and_page_revisions.rb +8 -0
- data/db/migrate/20140224205516_rename_traffic_schema.rb +40 -0
- data/db/pgtap/pgtap.sql +9034 -0
- data/db/test/landable.access_tokens.sql +13 -0
- data/db/test/landable.assets.sql +16 -0
- data/db/test/landable.authors.sql +22 -0
- data/db/test/landable.categories.sql +9 -0
- data/db/test/landable.page_revisions.sql +41 -0
- data/db/test/landable.pages.sql +19 -0
- data/db/test/landable.templates.sql +15 -0
- data/db/test/landable.themes.sql +25 -0
- data/doc/schema/access_token.json +22 -0
- data/doc/schema/asset.json +65 -0
- data/doc/schema/author.json +30 -0
- data/doc/schema/directory.json +24 -0
- data/doc/schema/page.json +95 -0
- data/doc/schema/page_revision.json +70 -0
- data/doc/schema/theme.json +37 -0
- data/doc/schema/uuid.json +6 -0
- data/features/api/access_tokens.feature +84 -0
- data/features/api/assets.feature +46 -0
- data/features/api/cors.feature +25 -0
- data/features/api/pages.feature +42 -0
- data/features/api/preview.feature +16 -0
- data/features/api/templates.feature +33 -0
- data/features/api/themes.feature +33 -0
- data/features/liquid/body.feature +35 -0
- data/features/liquid/drops/categories.feature +54 -0
- data/features/liquid/tags.feature +168 -0
- data/features/public/content_types.feature +17 -0
- data/features/public/publishing.feature +45 -0
- data/features/public/status_codes.feature +25 -0
- data/features/public/views.feature +17 -0
- data/features/step_definitions/asset_steps.rb +60 -0
- data/features/step_definitions/core_api_steps.rb +139 -0
- data/features/step_definitions/debug_steps.rb +3 -0
- data/features/step_definitions/factory_steps.rb +124 -0
- data/features/step_definitions/html_steps.rb +9 -0
- data/features/step_definitions/liquid_steps.rb +79 -0
- data/features/step_definitions/revision_steps.rb +5 -0
- data/features/step_definitions/theme_steps.rb +43 -0
- data/features/support/env.rb +66 -0
- data/features/support/usefulness.rb +13 -0
- data/landable.gemspec +54 -0
- data/lib/generators/landable/collection/collection_generator.rb +0 -0
- data/lib/generators/landable/collection/templates/stylesheets/landable/%file_name%.less +0 -0
- data/lib/generators/landable/collection/templates/stylesheets/landable/%file_name%/mixins.less +0 -0
- data/lib/generators/landable/collection/templates/stylesheets/landable/%file_name%/variables.less +0 -0
- data/lib/generators/landable/component/component_generator.rb +0 -0
- data/lib/generators/landable/component/templates/javascripts/landable/%file_name%.less +0 -0
- data/lib/generators/landable/component/templates/stylesheets/landable/%file_name%.less +0 -0
- data/lib/generators/landable/install_generator.rb +19 -0
- data/lib/generators/landable/landable_generator.rb +22 -0
- data/lib/generators/templates/landable.rb +34 -0
- data/lib/landable.rb +30 -0
- data/lib/landable/configuration.rb +115 -0
- data/lib/landable/core_ext/ipaddr.rb +18 -0
- data/lib/landable/engine.rb +69 -0
- data/lib/landable/error.rb +16 -0
- data/lib/landable/inflections.rb +4 -0
- data/lib/landable/layout.rb +60 -0
- data/lib/landable/liquid.rb +27 -0
- data/lib/landable/liquid/asset_tags.rb +76 -0
- data/lib/landable/liquid/drops.rb +46 -0
- data/lib/landable/liquid/filters.rb +11 -0
- data/lib/landable/liquid/tags.rb +91 -0
- data/lib/landable/migration.rb +40 -0
- data/lib/landable/mime_types.rb +15 -0
- data/lib/landable/partial.rb +46 -0
- data/lib/landable/seeds.rb +36 -0
- data/lib/landable/traffic.rb +34 -0
- data/lib/landable/traffic/crawl_tracker.rb +9 -0
- data/lib/landable/traffic/noop_tracker.rb +8 -0
- data/lib/landable/traffic/ping_tracker.rb +9 -0
- data/lib/landable/traffic/scan_tracker.rb +9 -0
- data/lib/landable/traffic/scrape_tracker.rb +9 -0
- data/lib/landable/traffic/tracker.rb +283 -0
- data/lib/landable/traffic/user_tracker.rb +65 -0
- data/lib/landable/version.rb +10 -0
- data/lib/tasks/landable/cucumber.rake +67 -0
- data/lib/tasks/landable/data.rake +166 -0
- data/lib/tasks/landable/pgtap.rake +26 -0
- data/lib/tasks/landable/rdoc.rake +11 -0
- data/lib/tasks/landable/seed.rake +16 -0
- data/lib/tasks/landable/spec.rake +15 -0
- data/script/cucumber +10 -0
- data/spec/concerns/landable/has_assets_spec.rb +75 -0
- data/spec/concerns/landable/table_name_spec.rb +15 -0
- data/spec/concerns/landable/traffic/table_name_spec.rb +16 -0
- data/spec/controllers/concerns/landable/variables_concern_spec.rb +66 -0
- data/spec/controllers/landable/api/assets_controller_spec.rb +24 -0
- data/spec/controllers/landable/api/categories_controller_spec.rb +45 -0
- data/spec/controllers/landable/api/directories_controller_spec.rb +56 -0
- data/spec/controllers/landable/api/page_revisions_controller_spec.rb +29 -0
- data/spec/controllers/landable/api/pages_controller_spec.rb +271 -0
- data/spec/controllers/landable/api_controller_spec.rb +189 -0
- data/spec/controllers/public/preview/page_revisions_controller_spec.rb +41 -0
- data/spec/controllers/public/preview/pages_controller_spec.rb +36 -0
- data/spec/controllers/public/sitemap_controller_spec.rb +25 -0
- data/spec/decorators/page_decorator_spec.rb +90 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/foo.jpg +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +10 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/controllers/priority_controller.rb +7 -0
- data/spec/dummy/app/helpers/application_helper.rb +5 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/layouts/priority.html.erb +18 -0
- data/spec/dummy/app/views/partials/_foobazz.html +1 -0
- data/spec/dummy/app/views/priority/show.html.erb +11 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +21 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +60 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/landable.rb +22 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/db/structure.sql +3736 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/factories/asset.rb +29 -0
- data/spec/factories/authors.rb +12 -0
- data/spec/factories/category.rb +6 -0
- data/spec/factories/page_revision.rb +6 -0
- data/spec/factories/pages.rb +33 -0
- data/spec/factories/template.rb +13 -0
- data/spec/factories/theme.rb +14 -0
- data/spec/fixtures/assets/cthulhu.jpg +0 -0
- data/spec/fixtures/assets/panda.png +0 -0
- data/spec/fixtures/assets/sloth.png +0 -0
- data/spec/fixtures/assets/small.pdf +0 -0
- data/spec/helpers/pages_helper_spec.rb +35 -0
- data/spec/lib/landable/configuration_spec.rb +20 -0
- data/spec/lib/landable/layout_spec.rb +25 -0
- data/spec/lib/landable/liquid_spec.rb +24 -0
- data/spec/lib/landable/migration_spec.rb +51 -0
- data/spec/lib/landable/partial_spec.rb +84 -0
- data/spec/lib/landable/tracking_spec.rb +62 -0
- data/spec/lib/landable/traffic_spec.rb +45 -0
- data/spec/models/landable/access_token_spec.rb +13 -0
- data/spec/models/landable/asset_spec.rb +48 -0
- data/spec/models/landable/directory_spec.rb +36 -0
- data/spec/models/landable/page/errors_spec.rb +30 -0
- data/spec/models/landable/page_revision_spec.rb +75 -0
- data/spec/models/landable/page_spec.rb +377 -0
- data/spec/models/landable/template_spec.rb +47 -0
- data/spec/models/landable/theme_spec.rb +8 -0
- data/spec/responders/page_render_responder_spec.rb +43 -0
- data/spec/routing/public_page_route_spec.rb +36 -0
- data/spec/services/landable/authentication_service_spec.rb +61 -0
- data/spec/services/landable/render_service_spec.rb +103 -0
- data/spec/services/landable/tidy_service_spec.rb +157 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/support/behaviors.rb +107 -0
- data/spec/support/carrier_wave.rb +17 -0
- data/spec/support/categories.yml +2 -0
- data/spec/support/helpers.rb +22 -0
- metadata +795 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Landable
|
|
4
|
+
describe TableName do
|
|
5
|
+
|
|
6
|
+
describe '#table_name' do
|
|
7
|
+
it 'should generate the correct table name' do
|
|
8
|
+
Page.send(:table_name).should == "#{Landable.configuration.database_schema_prefix}landable.pages"
|
|
9
|
+
PageRevision.send(:table_name).should == "#{Landable.configuration.database_schema_prefix}landable.page_revisions"
|
|
10
|
+
Theme.send(:table_name).should == "#{Landable.configuration.database_schema_prefix}landable.themes"
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Landable
|
|
4
|
+
module Traffic
|
|
5
|
+
describe TableName do
|
|
6
|
+
|
|
7
|
+
describe '#table_name' do
|
|
8
|
+
it 'should generate the correct table name' do
|
|
9
|
+
Visit.send(:table_name).should == "#{Landable.configuration.database_schema_prefix}landable_traffic.visits"
|
|
10
|
+
PageView.send(:table_name).should == "#{Landable.configuration.database_schema_prefix}landable_traffic.page_views"
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Landable
|
|
4
|
+
# descriptions
|
|
5
|
+
describe VariablesConcern, type: :controller do
|
|
6
|
+
# setup
|
|
7
|
+
controller(ApplicationController) do
|
|
8
|
+
protected
|
|
9
|
+
def hello_world
|
|
10
|
+
"i live in a giant bucket."
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def hello_cleveland
|
|
14
|
+
"i am a banana."
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
after(:each) do
|
|
19
|
+
controller.class.imported_variables.clear
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
before(:each) do
|
|
23
|
+
controller.class.instance_exec do
|
|
24
|
+
register_landable_variable :hello_world
|
|
25
|
+
register_landable_variable :is_rejected, :hello_cleveland
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# tests
|
|
30
|
+
it "should include the VariablesConcern module" do
|
|
31
|
+
# setup
|
|
32
|
+
# actions
|
|
33
|
+
# expectations
|
|
34
|
+
expect(controller).to be_a Landable::VariablesConcern
|
|
35
|
+
# end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should use the #register_landable_variable with a similarly named method" do
|
|
39
|
+
# setup
|
|
40
|
+
# actions
|
|
41
|
+
# expectations
|
|
42
|
+
expect(controller.fetch_landable_variables[:hello_world]).to eql("i live in a giant bucket.")
|
|
43
|
+
# end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "should use the #register_landable_variable with a custom named method" do
|
|
47
|
+
# setup
|
|
48
|
+
# actions
|
|
49
|
+
# expectations
|
|
50
|
+
expect(controller.fetch_landable_variables[:is_rejected]).to eql("i am a banana.")
|
|
51
|
+
# end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "should use the #register_landable_variable with a string-based name" do
|
|
55
|
+
# setup
|
|
56
|
+
# actions
|
|
57
|
+
# expectations
|
|
58
|
+
expect(controller.fetch_landable_variables['is_rejected']).to eql("i am a banana.")
|
|
59
|
+
# end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# end
|
|
66
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Landable::Api
|
|
4
|
+
describe AssetsController, json: true do
|
|
5
|
+
routes { Landable::Engine.routes }
|
|
6
|
+
|
|
7
|
+
describe '#update' do
|
|
8
|
+
include_examples 'Authenticated API controller', :make_request
|
|
9
|
+
|
|
10
|
+
let(:asset) { create :asset, description: "Not updated" }
|
|
11
|
+
|
|
12
|
+
def make_request
|
|
13
|
+
put :update, id: asset.id, asset: { description: "Updated" }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "updates the asset description" do
|
|
17
|
+
make_request
|
|
18
|
+
asset.reload
|
|
19
|
+
asset.description.should == "Updated"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Landable::Api
|
|
4
|
+
describe CategoriesController, json: true do
|
|
5
|
+
routes { Landable::Engine.routes }
|
|
6
|
+
|
|
7
|
+
describe '#show' do
|
|
8
|
+
include_examples 'Authenticated API controller', :make_request
|
|
9
|
+
|
|
10
|
+
let(:category) { create :category }
|
|
11
|
+
|
|
12
|
+
def make_request(id = category.id)
|
|
13
|
+
get :show, id: id
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'returns the selected category' do
|
|
17
|
+
make_request
|
|
18
|
+
response.status.should == 200
|
|
19
|
+
last_json['category']['id'].should == category.id
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it '404s on page not found' do
|
|
23
|
+
make_request random_uuid
|
|
24
|
+
response.status.should == 404
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe '#index' do
|
|
29
|
+
include_examples 'Authenticated API controller', :make_request
|
|
30
|
+
|
|
31
|
+
def make_request
|
|
32
|
+
get :index
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'returns all categories' do
|
|
36
|
+
Landable::Category.delete_all
|
|
37
|
+
create_list :category, 5
|
|
38
|
+
|
|
39
|
+
make_request
|
|
40
|
+
response.status.should == 200
|
|
41
|
+
last_json['categories'].size.should == 5
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Landable::Api
|
|
4
|
+
describe DirectoriesController, json: true do
|
|
5
|
+
routes { Landable::Engine.routes }
|
|
6
|
+
|
|
7
|
+
describe '#index' do
|
|
8
|
+
include_examples 'Authenticated API controller', :make_request
|
|
9
|
+
|
|
10
|
+
def make_request(ids = nil)
|
|
11
|
+
get :index, ids: ids
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def dirs
|
|
15
|
+
last_json['directories']
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def dir(path)
|
|
19
|
+
dirs.find { |dir| dir['id'] == path }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def subdirs(path)
|
|
23
|
+
dir(path)['subdirectory_ids']
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def pages(path)
|
|
27
|
+
dir(path)['page_ids']
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'defaults to the root path' do
|
|
31
|
+
pages = ['/a', '/b/c', '/b/d'].map { |path| create :page, path: path }
|
|
32
|
+
make_request
|
|
33
|
+
response.status.should == 200
|
|
34
|
+
|
|
35
|
+
dirs.length.should == 1
|
|
36
|
+
dirs.first['id'].should == '/'
|
|
37
|
+
|
|
38
|
+
subdirs('/').length.should == 1
|
|
39
|
+
pages('/').length.should == 1
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'returns multiple directory listings' do
|
|
43
|
+
pages = ['/a', '/b/c', '/b/d', '/c/e', '/c/f/g'].map { |path| create :page, path: path }
|
|
44
|
+
make_request ['/b', '/c']
|
|
45
|
+
response.status.should == 200
|
|
46
|
+
dirs.length.should == 2
|
|
47
|
+
|
|
48
|
+
pages('/b').length.should == 2
|
|
49
|
+
pages('/c').length.should == 1
|
|
50
|
+
|
|
51
|
+
subdirs('/b').length.should == 0
|
|
52
|
+
subdirs('/c').length.should == 1
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Landable::Api
|
|
4
|
+
describe PageRevisionsController, json: true do
|
|
5
|
+
routes { Landable::Engine.routes }
|
|
6
|
+
|
|
7
|
+
describe '#index' do
|
|
8
|
+
include_examples 'Authenticated API controller', :make_request
|
|
9
|
+
|
|
10
|
+
let(:page) { create :page }
|
|
11
|
+
|
|
12
|
+
def make_request(page_id = page.id)
|
|
13
|
+
get :index, page_id: page_id
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "returns all of a page's revisions" do
|
|
17
|
+
page.publish! author: current_author
|
|
18
|
+
make_request
|
|
19
|
+
response.status.should == 200
|
|
20
|
+
last_json['page_revisions'].length.should == 1
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "404s on page not found" do
|
|
24
|
+
make_request random_uuid
|
|
25
|
+
response.status.should == 404
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Landable::Api
|
|
4
|
+
describe PagesController, json: true do
|
|
5
|
+
routes { Landable::Engine.routes }
|
|
6
|
+
|
|
7
|
+
describe '#create' do
|
|
8
|
+
include_examples 'Authenticated API controller', :make_request
|
|
9
|
+
|
|
10
|
+
let(:default_params) do
|
|
11
|
+
{ page: attributes_for(:page) }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
let(:page) do
|
|
15
|
+
Landable::Page.where(path: default_params[:page][:path]).first
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def make_request(params = {})
|
|
19
|
+
post :create, default_params.deep_merge(page: params)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context 'success' do
|
|
23
|
+
it 'returns 201 Created' do
|
|
24
|
+
make_request
|
|
25
|
+
response.status.should == 201
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'returns header Location with the page URL' do
|
|
29
|
+
make_request
|
|
30
|
+
response.headers['Location'].should == page_url(page)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'renders the page as JSON' do
|
|
34
|
+
make_request
|
|
35
|
+
path, body = default_params[:page].values_at(:path, :body)
|
|
36
|
+
last_json['page'].should include('path' => path, 'body' => body)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context 'invalid' do
|
|
41
|
+
it 'returns 422 Unprocessable Entity' do
|
|
42
|
+
make_request path: nil
|
|
43
|
+
response.status.should == 422
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'includes the errors in the JSON response' do
|
|
47
|
+
make_request status_code: 302, redirect_url: nil
|
|
48
|
+
last_json['errors'].should have_key('redirect_url')
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe '#index' do
|
|
54
|
+
include_examples 'Authenticated API controller', :make_request
|
|
55
|
+
|
|
56
|
+
let(:pages) { @pages ||= create_list(:page, 5) }
|
|
57
|
+
before(:each) { pages }
|
|
58
|
+
|
|
59
|
+
def make_request(params = {})
|
|
60
|
+
get :index, params
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'renders pages as json' do
|
|
64
|
+
make_request
|
|
65
|
+
last_json['pages'].collect { |p| p['id'] }.sort.should == pages.map(&:id).sort
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'filters pages according to requested ids' do
|
|
69
|
+
filtered_for_pages = pages[0..2]
|
|
70
|
+
|
|
71
|
+
make_request ids: filtered_for_pages.map(&:id)
|
|
72
|
+
last_json['pages'].collect { |p| p['id'] }.sort.should == filtered_for_pages.map(&:id).sort
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
describe 'search' do
|
|
76
|
+
describe 'by path' do
|
|
77
|
+
before(:each) do
|
|
78
|
+
['/foo', '/foo/bar', '/foo/bar/baz', '/bar'].each do |path|
|
|
79
|
+
create :page, path: path
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it 'filters by starting path fragment' do
|
|
84
|
+
make_request search: {path: '/foo/ba'}
|
|
85
|
+
last_json['pages'].collect { |p| p['path'] }.should == ['/foo/bar', '/foo/bar/baz']
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it 'matches all paths with the search term in them' do
|
|
89
|
+
make_request search: {path: 'ba'}
|
|
90
|
+
last_json['pages'].collect { |p| p['path'] }.should == ['/bar', '/foo/bar', '/foo/bar/baz']
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it 'only include 100 results, and include the total result count as meta data' do
|
|
96
|
+
create_list :page, (100 - pages.size)
|
|
97
|
+
make_request search: {path: '/'}
|
|
98
|
+
|
|
99
|
+
last_json['pages'].size.should == 100
|
|
100
|
+
last_json['meta']['search']['total_results'].should == 100
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
describe '#show' do
|
|
105
|
+
include_examples 'Authenticated API controller', :make_request
|
|
106
|
+
let(:page) { @page || create(:page) }
|
|
107
|
+
|
|
108
|
+
def make_request(id = page.id)
|
|
109
|
+
get :show, id: id
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it 'renders the page as JSON' do
|
|
113
|
+
make_request
|
|
114
|
+
last_json['page']['body'].should == page.body
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it 'includes an empty meta_tags hash instead of a null' do
|
|
118
|
+
page.update_attributes meta_tags: nil
|
|
119
|
+
make_request
|
|
120
|
+
last_json['page']['meta_tags'].should == {}
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
context 'no such page' do
|
|
125
|
+
it 'returns 404' do
|
|
126
|
+
make_request random_uuid
|
|
127
|
+
response.status.should == 404
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
describe '#update' do
|
|
133
|
+
include_examples 'Authenticated API controller', :make_request
|
|
134
|
+
|
|
135
|
+
let(:page) { @page || create(:page) }
|
|
136
|
+
let(:default_params) do
|
|
137
|
+
{ page: { body: 'Different body content' } }
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def make_request(changes = {})
|
|
141
|
+
id = changes.delete(:id) || page.id
|
|
142
|
+
patch :update, default_params.deep_merge(id: id, page: changes)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it 'saves the changes' do
|
|
146
|
+
make_request body: 'updated body!'
|
|
147
|
+
response.status.should == 200
|
|
148
|
+
page.reload.body.should == 'updated body!'
|
|
149
|
+
page.reload.updated_by_author.should == current_author
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it 'renders the page as JSON' do
|
|
153
|
+
make_request body: 'also updated'
|
|
154
|
+
last_json['page']['body'].should == 'also updated'
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
context 'invalid' do
|
|
158
|
+
it 'returns 422 Unprocessable Entity' do
|
|
159
|
+
make_request path: nil
|
|
160
|
+
response.status.should == 422
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it 'includes the errors in the JSON response' do
|
|
164
|
+
make_request status_code: 302, redirect_url: nil
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
context 'no such page' do
|
|
169
|
+
it 'returns 404' do
|
|
170
|
+
make_request id: random_uuid
|
|
171
|
+
response.status.should == 404
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
context 'stale page' do
|
|
176
|
+
it 'throws error when stale body update' do
|
|
177
|
+
page.save!
|
|
178
|
+
page1 = Landable::Page.first
|
|
179
|
+
page2 = Landable::Page.first
|
|
180
|
+
|
|
181
|
+
page1.body = "duh"
|
|
182
|
+
expect{ page1.save! }.to_not raise_error
|
|
183
|
+
page2.body = "something"
|
|
184
|
+
expect{ page2.save! }.to raise_error(ActiveRecord::StaleObjectError)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it 'throws error when stale meta_tags update' do
|
|
188
|
+
page.save!
|
|
189
|
+
page1 = Landable::Page.first
|
|
190
|
+
page2 = Landable::Page.first
|
|
191
|
+
|
|
192
|
+
page1.meta_tags = "duh"
|
|
193
|
+
expect{ page1.save! }.to_not raise_error
|
|
194
|
+
page2.meta_tags = "something"
|
|
195
|
+
expect{ page2.save! }.to raise_error(ActiveRecord::StaleObjectError)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it 'throws error when stale path update' do
|
|
199
|
+
page.save!
|
|
200
|
+
page1 = Landable::Page.first
|
|
201
|
+
page2 = Landable::Page.first
|
|
202
|
+
|
|
203
|
+
page1.body = "duh"
|
|
204
|
+
expect{ page1.save! }.to_not raise_error
|
|
205
|
+
page2.body = "something"
|
|
206
|
+
expect{ page2.save! }.to raise_error(ActiveRecord::StaleObjectError)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
it 'throws error when stale multi-column update' do
|
|
210
|
+
page.save!
|
|
211
|
+
page1 = Landable::Page.first
|
|
212
|
+
page2 = Landable::Page.first
|
|
213
|
+
page1.body = "duh"
|
|
214
|
+
expect{ page1.save! }.to_not raise_error
|
|
215
|
+
page2.body = "something"
|
|
216
|
+
expect{ page2.save! }.to raise_error(ActiveRecord::StaleObjectError)
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
describe '#preview', json: false do
|
|
222
|
+
include_examples 'Authenticated API controller', :make_request
|
|
223
|
+
render_views
|
|
224
|
+
|
|
225
|
+
let(:theme) { create :theme, body: '<html><head>{% head_content %}</head><body>Theme content; page content: {{body}}</body></html>' }
|
|
226
|
+
|
|
227
|
+
before do
|
|
228
|
+
request.env['HTTP_ACCEPT'] = 'text/html'
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def make_request(attributes = attributes_for(:page, theme_id: theme.id))
|
|
232
|
+
post :preview, page: attributes
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
it 'renders JSON' do
|
|
236
|
+
request.env['HTTP_ACCEPT'] = 'application/json'
|
|
237
|
+
make_request
|
|
238
|
+
response.status.should == 200
|
|
239
|
+
last_json['page']['preview'].should be_present
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it 'renders the layout without content if the body is not present' do
|
|
243
|
+
request.env['HTTP_ACCEPT'] = 'application/json'
|
|
244
|
+
make_request attributes_for(:page, body: nil, theme_id: theme.id)
|
|
245
|
+
response.status.should == 200
|
|
246
|
+
last_json['page']['preview'].should include('Theme content')
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
it 'renders without a layout if no theme is present' do
|
|
250
|
+
request.env['HTTP_ACCEPT'] = 'application/json'
|
|
251
|
+
make_request attributes_for(:page, body: 'raw content', theme_id: nil)
|
|
252
|
+
response.status.should == 200
|
|
253
|
+
last_json['page']['preview'].should include('raw content')
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
it 'renders 30x pages with a link to the real thing' do
|
|
257
|
+
request.env['HTTP_ACCEPT'] = 'application/json'
|
|
258
|
+
make_request attributes_for(:page, :redirect, body: 'still here', theme_id: theme.id)
|
|
259
|
+
response.status.should == 200
|
|
260
|
+
last_json['page']['preview'].should include('301')
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
it 'renders 404 pages as if they were 200s' do
|
|
264
|
+
request.env['HTTP_ACCEPT'] = 'application/json'
|
|
265
|
+
make_request attributes_for(:page, :gone, body: 'still here', theme_id: theme.id)
|
|
266
|
+
response.status.should == 200
|
|
267
|
+
last_json['page']['preview'].should match(/still here/)
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|