landable 1.7.1.rc1 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.rbenv-gemsets +1 -0
- data/.travis.yml +20 -2
- data/CHANGELOG.md +8 -1
- data/Gemfile +14 -13
- data/Rakefile +0 -1
- data/app/controllers/landable/api/assets_controller.rb +49 -31
- data/app/controllers/landable/api/pages_controller.rb +64 -42
- data/app/controllers/landable/api/templates_controller.rb +37 -13
- data/app/controllers/landable/api/themes_controller.rb +35 -14
- data/app/models/concerns/landable/librarian.rb +36 -0
- data/app/models/landable/asset.rb +1 -0
- data/app/models/landable/page.rb +9 -0
- data/app/models/landable/page_revision.rb +52 -9
- data/app/models/landable/search_engine.rb +1 -1
- data/app/models/landable/template.rb +10 -0
- data/app/models/landable/template_revision.rb +1 -0
- data/app/models/landable/theme.rb +1 -0
- data/app/responders/landable/api_responder.rb +1 -1
- data/app/serializers/landable/asset_serializer.rb +1 -0
- data/app/serializers/landable/page_revision_serializer.rb +1 -0
- data/app/serializers/landable/page_serializer.rb +4 -13
- data/app/serializers/landable/template_serializer.rb +3 -3
- data/app/serializers/landable/theme_serializer.rb +1 -1
- data/app/services/landable/screenshot_service.rb +32 -0
- data/app/views/templates/preview.liquid +13 -11
- data/config/routes.rb +6 -3
- data/db/migrate/20140501171345_add_deleted_at_to_pages.rb +5 -0
- data/db/migrate/20140501171352_add_deleted_at_to_themes.rb +5 -0
- data/db/migrate/20140501171359_add_deleted_at_to_assets.rb +5 -0
- data/db/migrate/20140501171406_add_deleted_at_to_templates.rb +5 -0
- data/db/migrate/20140515164543_add_screenshot_to_page_revisions.rb +5 -0
- data/db/test/landable.general.sql +9 -0
- data/db/test/landable.page_revisions.sql +5 -3
- data/db/test/landable.templates.sql +29 -2
- data/db/test/landable.themes.sql +5 -2
- data/doc/schema/asset.json +5 -0
- data/doc/schema/page.json +5 -0
- data/doc/schema/page_revision.json +6 -1
- data/doc/schema/template.json +5 -0
- data/doc/schema/template_revision.json +5 -0
- data/doc/schema/theme.json +5 -0
- data/landable.gemspec +31 -33
- data/lib/generators/templates/landable.rb +6 -0
- data/lib/landable/configuration.rb +39 -6
- data/lib/landable/version.rb +3 -3
- data/lib/tasks/landable/pgtap.rake +1 -2
- data/script/pgtap +10 -0
- data/script/redb +0 -2
- data/spec/concerns/landable/librarian.rb +45 -0
- data/spec/controllers/public/preview/pages_controller_spec.rb +1 -1
- data/spec/dummy/db/.keep +0 -0
- data/spec/models/landable/page_revision_spec.rb +60 -2
- data/spec/models/landable/page_spec.rb +3 -1
- data/spec/services/landable/authentication_service_spec.rb +1 -1
- data/spec/services/landable/screenshot_service_spec.rb +43 -0
- data/spec/services/landable/tidy_service_spec.rb +3 -2
- metadata +67 -82
- data/landable-1.7.0.gem +0 -0
- data/spec/dummy/db/structure.sql +0 -3837
data/config/routes.rb
CHANGED
@@ -8,7 +8,7 @@ Landable::Engine.routes.draw do
|
|
8
8
|
id: /[%a-zA-Z0-9\/_.~-]*/
|
9
9
|
}
|
10
10
|
|
11
|
-
resources :assets, only: [:index, :show, :create, :update]
|
11
|
+
resources :assets, only: [:index, :show, :create, :update, :deactivate, :destroy]
|
12
12
|
|
13
13
|
concern :has_assets do
|
14
14
|
resources :assets, only: [:index, :update, :destroy]
|
@@ -18,12 +18,14 @@ Landable::Engine.routes.draw do
|
|
18
18
|
post 'screenshots', on: :member
|
19
19
|
end
|
20
20
|
|
21
|
-
resources :themes, only: [:index, :show, :create, :update], concerns: :has_assets do
|
21
|
+
resources :themes, only: [:index, :show, :create, :update, :destroy], concerns: :has_assets do
|
22
22
|
post 'preview', on: :collection
|
23
|
+
put 'reactivate', on: :member
|
23
24
|
end
|
24
25
|
|
25
|
-
resources :templates, only: [:index, :show, :create, :update] do
|
26
|
+
resources :templates, only: [:index, :show, :create, :update, :destroy, :reactivate] do
|
26
27
|
post 'publish', on: :member
|
28
|
+
put 'reactivate', on: :member
|
27
29
|
end
|
28
30
|
|
29
31
|
resources :template_revisions, only: [:index, :show] do
|
@@ -33,6 +35,7 @@ Landable::Engine.routes.draw do
|
|
33
35
|
resources :pages, concerns: [:has_assets, :has_screenshots] do
|
34
36
|
post 'preview', on: :collection
|
35
37
|
post 'publish', on: :member
|
38
|
+
put 'reactivate', on: :member
|
36
39
|
end
|
37
40
|
|
38
41
|
resources :page_revisions, only: [:index, :show], concerns: [:has_screenshots] do
|
@@ -4,7 +4,6 @@ SELECT PLAN(18);
|
|
4
4
|
|
5
5
|
--Verify existence of triggers and functions for page revisions
|
6
6
|
SELECT triggers_are('dummy_landable', 'page_revisions', ARRAY['dummy_landable_page_revisions__bfr_insert', 'dummy_landable_page_revisions__no_delete', 'dummy_landable_page_revisions__no_update'], 'dummy_landable.page_revisions should have triggers');
|
7
|
-
SELECT functions_are('dummy_landable', ARRAY['pages_revision_ordinal', 'tg_disallow'], 'dummy_Landable schema should have funcitons');
|
8
7
|
|
9
8
|
--Verify existence of foreign keys
|
10
9
|
SELECT col_is_fk('dummy_landable', 'page_revisions', 'page_id', 'page_revisions has page_id foreign key');
|
@@ -15,16 +14,19 @@ SELECT col_is_fk('dummy_landable', 'page_revisions', 'category_id', 'page_revisi
|
|
15
14
|
--Verify primary key
|
16
15
|
SELECT col_is_pk('dummy_landable', 'page_revisions', 'page_revision_id', 'page_revisions has primary key');
|
17
16
|
|
17
|
+
--Verify page revisions is empty
|
18
|
+
SELECT results_eq($$SELECT COUNT(*)::INTEGER FROM dummy_landable.page_revisions$$, $$SELECT 0$$, 'No revision records should exist');
|
19
|
+
|
18
20
|
--Insert test data
|
19
21
|
SELECT lives_ok($$INSERT INTO dummy_landable.pages (is_publishable, path, status_code) VALUES ('true', '/foo/bar', 200)$$);
|
20
22
|
SELECT lives_ok($$INSERT INTO dummy_landable.authors (email, username, first_name, last_name) VALUES ('jdoe@test.com', 'jdoe', 'john', 'doe')$$);
|
21
|
-
SELECT lives_ok($$INSERT INTO dummy_landable.page_revisions(page_id, author_id) SELECT page_id, author_id FROM dummy_landable.pages, dummy_landable.authors$$);
|
23
|
+
SELECT lives_ok($$INSERT INTO dummy_landable.page_revisions(page_id, author_id) SELECT page_id, author_id FROM dummy_landable.pages, dummy_landable.authors LIMIT 1$$);
|
22
24
|
|
23
25
|
--Verify ordinal is generated and populated automatically
|
24
26
|
SELECT results_eq($$SELECT max(ordinal) FROM dummy_landable.page_revisions$$, $$SELECT 1$$);
|
25
27
|
|
26
28
|
--Verify ordinal is incremented automatically
|
27
|
-
SELECT lives_ok($$INSERT INTO dummy_landable.page_revisions(page_id, author_id) SELECT page_id, author_id FROM dummy_landable.pages, dummy_landable.authors$$);
|
29
|
+
SELECT lives_ok($$INSERT INTO dummy_landable.page_revisions(page_id, author_id) SELECT page_id, author_id FROM dummy_landable.pages, dummy_landable.authors LIMIT 1$$);
|
28
30
|
SELECT results_eq($$SELECT max(ordinal) FROM dummy_landable.page_revisions$$, $$SELECT 2$$);
|
29
31
|
|
30
32
|
--Verify ordinals cannot be supplied in insert
|
@@ -1,6 +1,9 @@
|
|
1
1
|
BEGIN;
|
2
2
|
|
3
|
-
SELECT PLAN(
|
3
|
+
SELECT PLAN(18);
|
4
|
+
|
5
|
+
--Verify existence of triggers and functions for page revisions
|
6
|
+
SELECT triggers_are('dummy_landable', 'template_revisions', ARRAY['dummy_landable_template_revisions__bfr_insert', 'dummy_landable_template_revisions__no_delete', 'dummy_landable_template_revisions__no_update'], 'dummy_landable.template_revisions should have triggers');
|
4
7
|
|
5
8
|
SELECT col_is_pk('dummy_landable', 'templates', 'template_id', 'Template_id is pk');
|
6
9
|
SELECT col_not_null('dummy_landable', 'templates', 'name', 'name is NOT NULL');
|
@@ -10,6 +13,30 @@ SELECT col_not_null('dummy_landable', 'templates', 'description', 'description i
|
|
10
13
|
SELECT has_index('dummy_landable', 'templates', 'dummy_landable_templates__u_name', 'Index on name');
|
11
14
|
SELECT index_is_unique('dummy_landable', 'templates', 'dummy_landable_templates__u_name', 'name index is unique');
|
12
15
|
|
16
|
+
--Insert test data
|
17
|
+
SELECT lives_ok($$INSERT INTO dummy_landable.templates (name, slug, body, description) VALUES ('template1', 'template1', 'body1', 'test_body')$$);
|
18
|
+
SELECT lives_ok($$INSERT INTO dummy_landable.authors (email, username, first_name, last_name) VALUES ('jtemplate@test.com', 'jtemplate', 'john', 'template')$$);
|
19
|
+
SELECT lives_ok($$INSERT INTO dummy_landable.template_revisions(template_id, author_id, name) SELECT template_id, author_id, a.name FROM dummy_landable.templates a, dummy_landable.authors b WHERE a.name = 'template1' AND b.email = 'jtemplate@test.com' LIMIT 1$$);
|
20
|
+
|
21
|
+
--Verify ordinal is generated and populated automatically
|
22
|
+
SELECT results_eq($$SELECT max(ordinal) FROM dummy_landable.template_revisions WHERE name = 'template1' $$, $$SELECT 1$$);
|
23
|
+
|
24
|
+
--Verify ordinal is incremented automatically
|
25
|
+
SELECT lives_ok($$INSERT INTO dummy_landable.template_revisions(template_id, author_id, name) SELECT template_id, author_id, a.name FROM dummy_landable.templates a, dummy_landable.authors b WHERE a.name = 'template1' AND b.email = 'jtemplate@test.com' LIMIT 1$$);
|
26
|
+
SELECT results_eq($$SELECT max(ordinal) FROM dummy_landable.template_revisions WHERE name = 'template1'$$, $$SELECT 2$$);
|
27
|
+
|
28
|
+
--Verify ordinals cannot be supplied in insert
|
29
|
+
SELECT throws_matching($$INSERT INTO dummy_landable.template_revisions(ordinal, template_id, author_id) SELECT 1, template_id, author_id FROM dummy_landable.templates, dummy_landable.authors$$, 'ordinal');
|
30
|
+
|
31
|
+
--Verify cannot delete from template_revisions
|
32
|
+
SELECT throws_matching($$DELETE FROM dummy_landable.template_revisions$$, 'DELETEs are not allowed');
|
33
|
+
|
34
|
+
--Verify cannot update fields others than is_published, updated_atfor template_revisions
|
35
|
+
SELECT throws_matching($$UPDATE dummy_landable.template_revisions SET notes = 'blah'$$, 'UPDATEs are not allowed', 'Cannot update notes');
|
36
|
+
SELECT lives_ok($$UPDATE dummy_landable.template_revisions SET updated_at = now()$$, 'Can update updated_at');
|
37
|
+
SELECT lives_ok($$UPDATE dummy_landable.template_revisions SET is_published = 'true'$$, 'Can update is_published');
|
38
|
+
|
39
|
+
|
13
40
|
SELECT * FROM finish();
|
14
41
|
|
15
|
-
ROLLBACK;
|
42
|
+
ROLLBACK;
|
data/db/test/landable.themes.sql
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
BEGIN;
|
2
2
|
|
3
|
-
SELECT PLAN(
|
3
|
+
SELECT PLAN(14);
|
4
4
|
|
5
5
|
SELECT col_is_pk('dummy_landable', 'themes', 'theme_id', 'Theme_id is PK');
|
6
6
|
|
@@ -18,7 +18,10 @@ BEGIN;
|
|
18
18
|
|
19
19
|
SELECT index_is_unique('dummy_landable', 'themes', 'dummy_landable_themes__u_file', $$Unique index on file column.$$);
|
20
20
|
SELECT lives_ok($$INSERT INTO dummy_landable.themes (file, name, body, description, editable) VALUES ('filename', 'test1', 'body', 'test body', true)$$);
|
21
|
-
SELECT throws_matching($$INSERT INTO dummy_landable.themes (file, name, body, description) VALUES ('FILENAME', '
|
21
|
+
SELECT throws_matching($$INSERT INTO dummy_landable.themes (file, name, body, description) VALUES ('FILENAME', 'test2', 'body', 'test body')$$, '__u_file');
|
22
|
+
|
23
|
+
SELECT lives_ok($$INSERT INTO dummy_landable.themes (file, name, body, description, editable) VALUES ('filename2', 'test3', 'body', 'test body', true)$$);
|
24
|
+
SELECT throws_matching($$INSERT INTO dummy_landable.themes (file, name, body, description) VALUES ('FILENAME3', 'test3', 'body', 'test body')$$, '__u_name');
|
22
25
|
|
23
26
|
SELECT * FROM finish();
|
24
27
|
|
data/doc/schema/asset.json
CHANGED
data/doc/schema/page.json
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
"description": "A particular snapshot of a page which has, at some point, been published.",
|
4
4
|
"type": "object",
|
5
5
|
"additionalProperties": false,
|
6
|
-
"required": ["id", "page_id", "author_id", "notes", "is_published", "is_minor", "preview_path", "ordinal", "created_at", "updated_at"],
|
6
|
+
"required": ["id", "page_id", "author_id", "notes", "is_published", "is_minor", "preview_path", "ordinal", "screenshot_url", "created_at", "updated_at"],
|
7
7
|
|
8
8
|
"properties": {
|
9
9
|
"id": {
|
@@ -57,6 +57,11 @@
|
|
57
57
|
"minimum": 1
|
58
58
|
},
|
59
59
|
|
60
|
+
"screenshot_url": {
|
61
|
+
"type": ["string", "null"],
|
62
|
+
"format": "uri"
|
63
|
+
},
|
64
|
+
|
60
65
|
"created_at": {
|
61
66
|
"type": "string",
|
62
67
|
"format": "date-time"
|
data/doc/schema/template.json
CHANGED
data/doc/schema/theme.json
CHANGED
data/landable.gemspec
CHANGED
@@ -4,50 +4,48 @@ lib = File.expand_path('../lib', __FILE__)
|
|
4
4
|
$:.unshift(lib) unless $:.include?(lib)
|
5
5
|
|
6
6
|
# Maintain your gem's version:
|
7
|
-
require
|
7
|
+
require 'landable/version'
|
8
8
|
|
9
9
|
# Describe your gem and declare its dependencies:
|
10
10
|
Gem::Specification.new do |gem|
|
11
|
-
gem.name =
|
11
|
+
gem.name = 'landable'
|
12
12
|
gem.version = Landable::VERSION::STRING
|
13
13
|
|
14
|
-
gem.authors = [
|
15
|
-
gem.email = [
|
14
|
+
gem.authors = ['Team Trogdor']
|
15
|
+
gem.email = ['trogdor@enova.com']
|
16
16
|
|
17
|
-
gem.homepage =
|
17
|
+
gem.homepage = 'https://github.com/enova/landable'
|
18
18
|
|
19
|
-
gem.license =
|
19
|
+
gem.license = 'MIT-LICENSE'
|
20
20
|
|
21
|
-
gem.summary =
|
22
|
-
gem.description =
|
21
|
+
gem.summary = 'Mountable CMS engine for Rails'
|
22
|
+
gem.description = 'Landing page storage, rendering, tracking, and management API'
|
23
23
|
|
24
24
|
gem.files = `git ls-files`.split($/)
|
25
25
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
26
26
|
gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
27
27
|
|
28
|
-
gem.require_paths = [
|
29
|
-
|
30
|
-
gem.add_dependency
|
31
|
-
gem.add_dependency
|
32
|
-
gem.add_dependency
|
33
|
-
gem.add_dependency
|
34
|
-
gem.add_dependency
|
35
|
-
gem.add_dependency
|
36
|
-
gem.add_dependency
|
37
|
-
gem.add_dependency
|
38
|
-
gem.add_dependency
|
39
|
-
|
40
|
-
gem.add_development_dependency
|
41
|
-
gem.add_development_dependency
|
42
|
-
gem.add_development_dependency
|
43
|
-
gem.add_development_dependency
|
44
|
-
gem.add_development_dependency
|
45
|
-
gem.add_development_dependency
|
46
|
-
gem.add_development_dependency
|
47
|
-
gem.add_development_dependency
|
48
|
-
gem.add_development_dependency
|
49
|
-
gem.add_development_dependency
|
50
|
-
gem.add_development_dependency
|
51
|
-
gem.add_development_dependency "faker"
|
52
|
-
gem.add_development_dependency "bundler_geminabox"
|
28
|
+
gem.require_paths = ['lib']
|
29
|
+
|
30
|
+
gem.add_dependency 'rails', '~> 4.0'
|
31
|
+
gem.add_dependency 'rack-cors', '>= 0.2.7'
|
32
|
+
gem.add_dependency 'active_model_serializers', '~> 0.8'
|
33
|
+
gem.add_dependency 'carrierwave'
|
34
|
+
gem.add_dependency 'liquid'
|
35
|
+
gem.add_dependency 'fog'
|
36
|
+
gem.add_dependency 'rest-client'
|
37
|
+
gem.add_dependency 'builder'
|
38
|
+
gem.add_dependency 'lookup_by', '> 0.4.0'
|
39
|
+
|
40
|
+
gem.add_development_dependency 'pg'
|
41
|
+
gem.add_development_dependency 'rspec-rails', '~> 2.14.2'
|
42
|
+
gem.add_development_dependency 'factory_girl_rails', '~> 4.2.0'
|
43
|
+
gem.add_development_dependency 'json-schema', '= 2.1.3'
|
44
|
+
gem.add_development_dependency 'rack-schema'
|
45
|
+
gem.add_development_dependency 'cucumber', '= 1.3.14'
|
46
|
+
gem.add_development_dependency 'database_cleaner'
|
47
|
+
gem.add_development_dependency 'simplecov'
|
48
|
+
gem.add_development_dependency 'valid_attribute'
|
49
|
+
gem.add_development_dependency 'pry'
|
50
|
+
gem.add_development_dependency 'faker'
|
53
51
|
end
|
@@ -25,6 +25,12 @@ Landable.configure do |config|
|
|
25
25
|
# Uncomment to enable tracking of all requests.
|
26
26
|
# Set to :html to track only HTML requests.
|
27
27
|
# config.traffic_enabled = true
|
28
|
+
|
29
|
+
# If you're using Landable with Publicist, add its url here. (required for screenshots)
|
30
|
+
# config.publicist_url = 'http://publicist.dev/'
|
31
|
+
|
32
|
+
# Where is your site deployed? (required for screenshots)
|
33
|
+
# config.public_url = 'http://myapp.dev/'
|
28
34
|
end
|
29
35
|
|
30
36
|
# Configure asset uploads. Assets will be uploaded to public/uploads by default.
|
@@ -1,8 +1,14 @@
|
|
1
1
|
module Landable
|
2
2
|
class Configuration
|
3
|
-
|
4
|
-
attr_writer :
|
5
|
-
attr_writer :
|
3
|
+
attr_accessor :api_url, :public_url
|
4
|
+
attr_writer :api_namespace, :public_namespace
|
5
|
+
attr_writer :api_host, :public_host
|
6
|
+
attr_writer :categories
|
7
|
+
attr_writer :screenshots_enabled
|
8
|
+
attr_writer :traffic_enabled
|
9
|
+
attr_writer :sitemap_exclude_categories, :sitemap_protocol, :sitemap_host, :sitemap_additional_paths
|
10
|
+
attr_writer :reserved_paths, :partials_to_templates, :database_schema_prefix
|
11
|
+
attr_writer :publicist_url
|
6
12
|
|
7
13
|
def authenticators
|
8
14
|
@authenticators || raise("No Landable authenticator configured.")
|
@@ -14,13 +20,36 @@ module Landable
|
|
14
20
|
|
15
21
|
alias :authenticator= :authenticators=
|
16
22
|
|
23
|
+
def publicist_url
|
24
|
+
@publicist_url ||= 'publicist.dev'
|
25
|
+
end
|
26
|
+
|
27
|
+
def api_uri
|
28
|
+
if api_url.present?
|
29
|
+
@api_uri ||= URI(api_url)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def api_host
|
34
|
+
@api_host ||= api_uri.try(:host)
|
35
|
+
end
|
36
|
+
|
17
37
|
def api_namespace
|
18
|
-
@api_namespace ||= '/api/landable'
|
38
|
+
@api_namespace ||= (api_uri.try(:path).presence || '/api/landable')
|
39
|
+
end
|
40
|
+
|
41
|
+
def public_uri
|
42
|
+
if public_url.present?
|
43
|
+
@public_uri ||= URI(public_url)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def public_host
|
48
|
+
@public_host ||= public_uri.try(:host)
|
19
49
|
end
|
20
50
|
|
21
51
|
def public_namespace
|
22
|
-
|
23
|
-
@public_namespace ||= '/'
|
52
|
+
@public_namespace ||= (public_uri.try(:path).presence || '')
|
24
53
|
end
|
25
54
|
|
26
55
|
def database_schema_prefix
|
@@ -67,6 +96,10 @@ module Landable
|
|
67
96
|
@sitemap_host
|
68
97
|
end
|
69
98
|
|
99
|
+
def screenshots_enabled
|
100
|
+
@screenshots_enabled ||= false
|
101
|
+
end
|
102
|
+
|
70
103
|
def traffic_enabled
|
71
104
|
@traffic_enabled ||= false
|
72
105
|
end
|
data/lib/landable/version.rb
CHANGED
@@ -16,8 +16,7 @@ namespace :landable do
|
|
16
16
|
else
|
17
17
|
# Load pgtap functions into database. Will not complain if already loaded.
|
18
18
|
ActiveRecord::Base.connection.execute(IO.read("#{dbdir}/pgtap/pgtap.sql"))
|
19
|
-
|
20
|
-
sh "cd #{dbdir}/test && pg_prove -d #{ActiveRecord::Base.connection.current_database} #{tests}"
|
19
|
+
sh "cd #{Rails.root}/../../script && ./pgtap"
|
21
20
|
end
|
22
21
|
end
|
23
22
|
end
|