landable 1.9.0.rc1 → 1.9.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -1
  3. data/app/controllers/landable/api/access_tokens_controller.rb +6 -6
  4. data/app/controllers/landable/api/audits_controller.rb +42 -0
  5. data/app/controllers/landable/api/configurations_controller.rb +13 -0
  6. data/app/controllers/landable/api/pages_controller.rb +7 -4
  7. data/app/controllers/landable/api/templates_controller.rb +6 -6
  8. data/app/models/concerns/landable/has_templates.rb +60 -0
  9. data/app/models/landable/audit.rb +9 -0
  10. data/app/models/landable/page.rb +4 -0
  11. data/app/models/landable/page_revision.rb +22 -1
  12. data/app/models/landable/template.rb +13 -0
  13. data/app/models/landable/template_revision.rb +1 -0
  14. data/app/serializers/landable/audit_serializer.rb +12 -0
  15. data/app/serializers/landable/configuration_serializer.rb +5 -0
  16. data/app/serializers/landable/page_serializer.rb +9 -4
  17. data/app/serializers/landable/template_serializer.rb +7 -3
  18. data/config/routes.rb +6 -0
  19. data/db/migrate/20140509192856_create_audits.rb +19 -0
  20. data/db/migrate/20140522202332_join_table_templates_pages.rb +8 -0
  21. data/doc/schema/audit.json +30 -0
  22. data/doc/schema/page.json +5 -0
  23. data/doc/schema/template.json +5 -1
  24. data/lib/landable/configuration.rb +5 -1
  25. data/lib/landable/liquid/tags.rb +2 -0
  26. data/lib/landable/version.rb +1 -1
  27. data/spec/concerns/landable/has_templates_spec.rb +62 -0
  28. data/spec/controllers/landable/api/audits_controller_spec.rb +150 -0
  29. data/spec/controllers/landable/api/configuration_controller_spec.rb +20 -0
  30. data/spec/dummy/config/initializers/landable.rb +2 -0
  31. data/spec/factories/audit.rb +7 -0
  32. data/spec/models/landable/audit_spec.rb +5 -0
  33. data/spec/models/landable/page_revision_spec.rb +16 -1
  34. data/spec/models/landable/template_revision_spec.rb +1 -1
  35. data/spec/models/landable/template_spec.rb +9 -0
  36. metadata +24 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fa1b60f79220988343e9f1438585cecb2dbc9098
4
- data.tar.gz: 16442db46400bebecdd4fe19f914c64e65335d01
3
+ metadata.gz: 1ae45a1d06e787c18d34b13ac783b226052dcf27
4
+ data.tar.gz: 549abf6b33387d0e86eb3ec840608dbcd9b40eb0
5
5
  SHA512:
6
- metadata.gz: eacec5ab37461a178bc801e0d44cc2ec6d401a1e5bd12d421c32ba864b6440ffee03d5d85575d29e4e7b7815547ec8b9214591e4a9e661301b0dccbfa8e5d4ca
7
- data.tar.gz: 81e6d79b97f684452ae2e17368c60cd1a439f7bcb3b0120c1ad91f04a017a0a6eb24da5fa9f7a058c0b1fd31c88a5dde4141a139e9b557612877aafd9c5511df
6
+ metadata.gz: bfea9429af570577f8da59c425f73c13688422891dac7dca7530a41841bfda38bb98f50a82a23d39f023cb6e3de2071e1f77ca82cea2013f70333854d318e2e6
7
+ data.tar.gz: a4ecfb3df6a1d97a38d1ff8769f6a574f7f738f51cb0c11f2ea341887c38fd4c66b49c9d33fcb13c2c623451cec81dbf3a2ad27491436a628b231be94d47ab86
data/CHANGELOG.md CHANGED
@@ -2,7 +2,10 @@
2
2
 
3
3
  See README.md before updating this file.
4
4
 
5
- ## Unreleased [#](https://github.com/enova/landable/compare/v1.9.0.rc1...master)
5
+ ## Unreleased [#](https://github.com/enova/landable/compare/v1.9.0.rc2...master)
6
+
7
+ ## 1.9.0.rc1 [#](https://github.com/enova/landable/compare/v1.9.0.rc1...v1.9.0.rc2)
8
+ * Audits [*10]
6
9
 
7
10
  ## 1.9.0.rc1 [#](https://github.com/enova/landable/compare/v1.8.0...v1.9.0.rc1)
8
11
  * Expose the tracker's referer domain & path [#14]
@@ -36,13 +36,13 @@ module Landable
36
36
 
37
37
  private
38
38
 
39
- def find_own_access_token(id = params[:id])
40
- current_author.access_tokens.fresh.find(id)
41
- end
39
+ def find_own_access_token(id = params[:id])
40
+ current_author.access_tokens.fresh.find(id)
41
+ end
42
42
 
43
- def asset_token_params
44
- params.require(:access_token).permit(:username, :password)
45
- end
43
+ def asset_token_params
44
+ params.require(:access_token).permit(:username, :password)
45
+ end
46
46
  end
47
47
  end
48
48
  end
@@ -0,0 +1,42 @@
1
+ require_dependency "landable/api_controller"
2
+
3
+ module Landable
4
+ module Api
5
+ class AuditsController < ApiController
6
+ def index
7
+ if params[:auditable_id].present?
8
+ audits = Audit.where(auditable_id: params[:auditable_id])
9
+ else
10
+ audits = Audit.order('created_at DESC')
11
+ end
12
+ respond_with audits
13
+ end
14
+
15
+ def show
16
+ respond_with Audit.find(params[:id])
17
+ end
18
+
19
+ def create
20
+ if params[:page_id].present?
21
+ type_id = params[:page_id]
22
+ type = 'Landable::Page'
23
+ else
24
+ type_id = params[:template_id]
25
+ type = 'Landable::Template'
26
+ end
27
+
28
+ audit = Audit.new audit_params.merge(auditable_id: type_id,
29
+ auditable_type: type)
30
+ audit.save!
31
+
32
+ respond_with audit, status: :created, location: audit_url(audit)
33
+ end
34
+
35
+ private
36
+ def audit_params
37
+ params[:audit][:flags] ||= []
38
+ params.require(:audit).permit(:id, :approver, :notes, :created_at, flags: [])
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,13 @@
1
+ require_dependency "landable/api_controller"
2
+
3
+ module Landable
4
+ module Api
5
+ class ConfigurationsController < ApiController
6
+ skip_before_filter :require_author!
7
+
8
+ def show
9
+ respond_with configurations: [Landable.configuration.as_json]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -99,10 +99,6 @@ module Landable
99
99
  end
100
100
  end
101
101
 
102
- def page_params
103
- params.require(:page).permit(:id, :path, :theme_id, :category_id, :title, :head_content, :body, :status_code, :redirect_url, :lock_version, :abstract, :hero_asset_name, meta_tags: [:description, :keywords, :robots])
104
- end
105
-
106
102
  def with_format(format, &block)
107
103
  old_formats = formats
108
104
 
@@ -113,6 +109,13 @@ module Landable
113
109
  self.formats = old_formats
114
110
  end
115
111
  end
112
+
113
+ def page_params
114
+ params[:page][:audit_flags] ||= []
115
+ params.require(:page).permit(:id, :path, :theme_id, :category_id, :title, :head_content, :body, :status_code, :redirect_url, :lock_version, :abstract, :hero_asset_name,
116
+ audit_flags: [],
117
+ meta_tags: [:description, :keywords, :robots])
118
+ end
116
119
  end
117
120
  end
118
121
  end
@@ -49,15 +49,15 @@ module Landable
49
49
  end
50
50
 
51
51
  private
52
- def load_template
53
- @template = Template.find(params[:id])
54
- end
55
-
56
52
  def template_params
57
- params.require(:template).permit(:id, :name, :body, :description, :thumbnail_url, :slug, :is_layout, :is_publishable)
53
+ params.require(:template).permit(:id, :name, :body, :description, :thumbnail_url,
54
+ :slug, :is_layout, :is_publishable,
55
+ audit_flags: [])
58
56
  end
59
57
 
60
- # end
58
+ def load_template
59
+ @template = Template.find(params[:id])
60
+ end
61
61
  end
62
62
  end
63
63
  end
@@ -0,0 +1,60 @@
1
+ require_dependency 'landable/liquid'
2
+
3
+ module Landable
4
+ module HasTemplates
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ has_and_belongs_to_many :templates, class_name: 'Landable::Template', join_table: templates_join_table_name
9
+
10
+ before_save :save_templates!
11
+
12
+ def template_names
13
+ # sticking with what we know about liquid, rather than doing regex.
14
+ # (though regex may be faster, should we need that optimization later.)
15
+ @template_names ||= begin
16
+ template = ::Liquid::Template.parse(body)
17
+ template_names_for_node template.root
18
+ end
19
+ end
20
+
21
+ def templates
22
+ Landable::Template.where(slug: template_names)
23
+ end
24
+
25
+ # passthrough for body=; clears the template_names cache in the process
26
+ def body= body_val
27
+ @template_slug = nil
28
+ @asset_names = nil
29
+ self[:body] = body_val
30
+ end
31
+
32
+ # this looks weird; I swear it works
33
+ def save_templates!
34
+ self.templates = self.templates
35
+ end
36
+
37
+ private
38
+
39
+ def template_names_for_node node, names = []
40
+ # set up a recursing function to search for template tags
41
+ if node.is_a? Landable::Liquid::TemplateTag
42
+ names << node.template_slug unless names.include? node.template_slug
43
+ end
44
+
45
+ if node.respond_to? :nodelist and node.nodelist
46
+ node.nodelist.each { |node| template_names_for_node node, names }
47
+ end
48
+
49
+ names
50
+ end
51
+
52
+ end
53
+
54
+ module ClassMethods
55
+ def templates_join_table_name
56
+ "#{Landable.configuration.database_schema_prefix}landable.#{self.name.underscore.split('/').last}_templates"
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,9 @@
1
+ module Landable
2
+ class Audit < ActiveRecord::Base
3
+ include Landable::TableName
4
+
5
+ validates :approver, presence: true
6
+
7
+ belongs_to :auditable, polymorphic: true
8
+ end
9
+ end
@@ -8,6 +8,7 @@ module Landable
8
8
  class Page < ActiveRecord::Base
9
9
  include ActionView::Helpers::TagHelper
10
10
  include Landable::HasAssets
11
+ include Landable::HasTemplates
11
12
  include Landable::Engine.routes.url_helpers
12
13
  include Landable::TableName
13
14
  include Landable::Librarian
@@ -34,6 +35,9 @@ module Landable
34
35
  belongs_to :hero_asset, class_name: 'Landable::Asset'
35
36
  has_many :revisions, class_name: 'Landable::PageRevision'
36
37
  has_many :screenshots, class_name: 'Landable::Screenshot', as: :screenshotable
38
+ has_many :audits, class_name: 'Landable::Audit', as: :auditable
39
+
40
+ delegate :republish!, to: :published_revision
37
41
 
38
42
  scope :imported, -> { where("imported_at IS NOT NULL") }
39
43
  scope :sitemappable, -> { where("COALESCE(meta_tags -> 'robots' NOT LIKE '%noindex%', TRUE)")
@@ -15,7 +15,8 @@ module Landable
15
15
  'published_revision_id',
16
16
  'is_publishable',
17
17
  'updated_by_author_id',
18
- 'lock_version'
18
+ 'lock_version',
19
+ 'audit_flags'
19
20
  ]
20
21
 
21
22
  cattr_accessor :ignored_page_attributes
@@ -65,6 +66,26 @@ module Landable
65
66
  update_attribute :is_published, false
66
67
  end
67
68
 
69
+ def republish!(options)
70
+ unpublish!
71
+ PageRevision.create!(page_id: self.page_id,
72
+ title: self.title,
73
+ meta_tags: page.meta_tags,
74
+ head_content: page.head_content,
75
+ body: self.body,
76
+ path: self.path,
77
+ redirect_url: self.redirect_url,
78
+ status_code: self.status_code,
79
+ theme_id: self.theme_id,
80
+ category_id: self.category_id,
81
+ abstract: self.abstract,
82
+ hero_asset_id: self.hero_asset_id,
83
+ notes: "Publishing update for template #{options[:template]}: #{options[:notes]}",
84
+ is_minor: options[:is_minor],
85
+ author_id: options[:author_id],
86
+ is_published: true)
87
+ end
88
+
68
89
  def preview_url
69
90
  begin
70
91
  public_preview_page_revision_url(self, host: Landable.configuration.public_host)
@@ -12,8 +12,11 @@ module Landable
12
12
 
13
13
 
14
14
  belongs_to :published_revision, class_name: 'Landable::TemplateRevision'
15
+ has_many :audits, class_name: 'Landable::Audit', as: :auditable
15
16
  has_many :revisions, class_name: 'Landable::TemplateRevision'
16
17
 
18
+ has_and_belongs_to_many :pages, join_table: Page.templates_join_table_name
19
+
17
20
  before_save -> template {
18
21
  template.is_publishable = true unless template.published_revision_id_changed?
19
22
  }
@@ -38,6 +41,16 @@ module Landable
38
41
  published_revision.unpublish! if published_revision
39
42
  revision = revisions.create! options
40
43
  update_attributes!(published_revision: revision, is_publishable: false)
44
+
45
+ # Republish Templates Pages Last Page Revision
46
+ republish_associated_pages(options)
47
+ end
48
+ end
49
+
50
+ def republish_associated_pages(options)
51
+ options[:template] = self.name
52
+ pages.each do |page|
53
+ page.republish!(options) if page.published?
41
54
  end
42
55
  end
43
56
 
@@ -11,6 +11,7 @@ module Landable
11
11
  'thumbnail_url',
12
12
  'is_layout',
13
13
  'is_publishable',
14
+ 'audit_flags',
14
15
  'deleted_at'
15
16
  ]
16
17
 
@@ -0,0 +1,12 @@
1
+ module Landable
2
+ class AuditSerializer < ActiveModel::Serializer
3
+ attributes :id, :flags, :notes, :approver
4
+ attributes :auditable_type, :auditable_id, :created_at
5
+
6
+ def auditable_type
7
+ if object.auditable_type.present?
8
+ object.auditable_type.underscore.gsub(/^landable\//, '')
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ module Landable
2
+ class ConfigurationSerializer < ActiveModel::Serializer
3
+ attributes :audit_flags
4
+ end
5
+ end
@@ -1,9 +1,14 @@
1
1
  module Landable
2
2
  class PageSerializer < ActiveModel::Serializer
3
-
4
- attributes :abstract, :body, :deleted_at, :head_content, :hero_asset_name,
5
- :id, :is_publishable, :lock_version, :meta_tags, :path,
6
- :preview_path, :redirect_url, :status_code, :title
3
+ attributes :id
4
+ attributes :path, :title, :body
5
+ attributes :head_content, :meta_tags
6
+ attributes :status_code, :redirect_url
7
+ attributes :is_publishable, :preview_path
8
+ attributes :audit_flags
9
+ attributes :hero_asset_name, :abstract
10
+ attributes :lock_version
11
+ attributes :deleted_at
7
12
 
8
13
  embed :ids
9
14
  has_one :theme
@@ -1,8 +1,12 @@
1
1
  module Landable
2
2
  class TemplateSerializer < ActiveModel::Serializer
3
-
4
- attributes :body, :deleted_at, :description, :editable, :file, :id,
5
- :is_layout, :is_publishable, :name, :slug, :thumbnail_url
3
+ attributes :id
4
+ attributes :name, :body, :description
5
+ attributes :thumbnail_url, :slug
6
+ attributes :is_layout, :is_publishable
7
+ attributes :file, :editable
8
+ attributes :audit_flags
9
+ attributes :deleted_at
6
10
 
7
11
  embed :ids
8
12
  has_one :published_revision
data/config/routes.rb CHANGED
@@ -10,6 +10,10 @@ Landable::Engine.routes.draw do
10
10
 
11
11
  resources :assets, only: [:index, :show, :create, :update, :deactivate, :destroy]
12
12
 
13
+ resources :audits, only: [:index, :show]
14
+
15
+ get 'configuration', to: 'configurations#show'
16
+
13
17
  concern :has_assets do
14
18
  resources :assets, only: [:index, :update, :destroy]
15
19
  end
@@ -26,6 +30,7 @@ Landable::Engine.routes.draw do
26
30
  resources :templates, only: [:index, :show, :create, :update, :destroy, :reactivate] do
27
31
  post 'publish', on: :member
28
32
  put 'reactivate', on: :member
33
+ resources :audits, only: [:create]
29
34
  end
30
35
 
31
36
  resources :template_revisions, only: [:index, :show] do
@@ -36,6 +41,7 @@ Landable::Engine.routes.draw do
36
41
  post 'preview', on: :collection
37
42
  post 'publish', on: :member
38
43
  put 'reactivate', on: :member
44
+ resources :audits, only: [:create]
39
45
  end
40
46
 
41
47
  resources :page_revisions, only: [:index, :show], concerns: [:has_screenshots] do
@@ -0,0 +1,19 @@
1
+ class CreateAudits < ActiveRecord::Migration
2
+ def change
3
+ # Audit Flags Field on Pages, Templates
4
+ add_column "#{Landable.configuration.database_schema_prefix}landable.pages", :audit_flags, :string, array: true, default: []
5
+ add_column "#{Landable.configuration.database_schema_prefix}landable.templates", :audit_flags, :string, array: true, default: []
6
+
7
+ # Audit Model
8
+ create_table "#{Landable.configuration.database_schema_prefix}landable.audits" do |t|
9
+ t.uuid :auditable_id
10
+ t.string :auditable_type
11
+
12
+ t.text :notes
13
+ t.text :approver
14
+ t.string :flags, array: true, default: []
15
+
16
+ t.timestamps
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,8 @@
1
+ class JoinTableTemplatesPages < ActiveRecord::Migration
2
+ def change
3
+ create_table "#{Landable.configuration.database_schema_prefix}landable.page_templates", id: :uuid, primary_key: :page_template_id do |t|
4
+ t.uuid :page_id, null: false
5
+ t.uuid :template_id, null: false
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,30 @@
1
+ {
2
+ "title": "PageAudits / TemplateAudits / Audits",
3
+ "description": "Audits SERVED(!) by landable",
4
+ "type": "object",
5
+ "additionalProperties": false,
6
+ "required": ["id"],
7
+
8
+ "properties": {
9
+ "id": {
10
+ "$ref": "uuid.json#"
11
+ },
12
+
13
+ "notes": {
14
+ "type": ["text", "null"]
15
+ },
16
+
17
+ "approver": {
18
+ "type": ["text", "null"]
19
+ },
20
+
21
+ "flags": {
22
+ "type": ["array", "null"]
23
+ },
24
+
25
+ "created_at": {
26
+ "type": "string",
27
+ "format": "date-time"
28
+ }
29
+ }
30
+ }
data/doc/schema/page.json CHANGED
@@ -95,6 +95,11 @@
95
95
 
96
96
  "hero_asset_name": {
97
97
  "type": ["string", "null"]
98
+ },
99
+
100
+ "audit_flags" : {
101
+ "type" : ["array", "null"],
102
+ "items" : { "type" : "string"}
98
103
  }
99
104
  }
100
105
  }
@@ -61,7 +61,11 @@
61
61
  "deleted_at": {
62
62
  "type": "date",
63
63
  "format": "date-time"
64
- }
64
+ },
65
65
 
66
+ "audit_flags" : {
67
+ "type" : ["array", "null"],
68
+ "items" : { "type" : "string"}
69
+ }
66
70
  }
67
71
  }
@@ -8,7 +8,7 @@ module Landable
8
8
  attr_writer :traffic_enabled
9
9
  attr_writer :sitemap_exclude_categories, :sitemap_protocol, :sitemap_host, :sitemap_additional_paths
10
10
  attr_writer :reserved_paths, :partials_to_templates, :database_schema_prefix
11
- attr_writer :publicist_url
11
+ attr_writer :publicist_url, :audit_flags
12
12
 
13
13
  def authenticators
14
14
  @authenticators || raise("No Landable authenticator configured.")
@@ -48,6 +48,10 @@ module Landable
48
48
  @public_host ||= public_uri.try(:host)
49
49
  end
50
50
 
51
+ def audit_flags
52
+ @audit_flags ||= []
53
+ end
54
+
51
55
  def public_namespace
52
56
  @public_namespace ||= (public_uri.try(:path).presence || '')
53
57
  end
@@ -62,6 +62,8 @@ module Landable
62
62
  end
63
63
 
64
64
  class TemplateTag < Tag
65
+ attr_accessor :template_slug
66
+
65
67
  def initialize(tag, param, tokens)
66
68
  param_tokens = param.split(/\s+/)
67
69
  @template_slug = param_tokens.shift
@@ -3,7 +3,7 @@ module Landable
3
3
  MAJOR = 1
4
4
  MINOR = 9
5
5
  PATCH = 0
6
- PRE = 'rc1'
6
+ PRE = 'rc2'
7
7
 
8
8
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
9
9
  end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ module Landable
4
+ describe HasTemplates do
5
+
6
+ before(:each) { create_list :template, 3 }
7
+
8
+ let(:templates) { Landable::Template.last(3) }
9
+ let(:subject) {
10
+ build :page, {
11
+ body: "
12
+ <div>{% template #{templates[0].slug} %}</div>
13
+ <div>{% template #{templates[1].slug} %}</div>
14
+ <div>{% template #{templates[2].slug} %}</div>
15
+ "
16
+ }
17
+ }
18
+
19
+ describe '#templates' do
20
+ it 'should return templates' do
21
+ slugs = [templates[0].slug, templates[1].slug, templates[2].slug]
22
+ subject.templates.should == Landable::Template.where(slug: slugs)
23
+ end
24
+ end
25
+
26
+ describe '#template_names' do
27
+ it 'should pull template slugs out of the body' do
28
+ subject.template_names.sort.should == templates.map(&:slug).uniq.sort
29
+ end
30
+ end
31
+
32
+ describe '#save_templates!' do
33
+ it 'should save the templates' do
34
+ assets_double = double()
35
+ subject.should_receive(:templates) { assets_double }
36
+ subject.should_receive(:templates=).with(assets_double)
37
+ subject.save_templates!
38
+ end
39
+
40
+ it 'should be called during save' do
41
+ subject.should_receive :save_templates!
42
+ subject.save!
43
+ end
44
+ end
45
+
46
+ describe 'body=' do
47
+ it 'should reset the template_slug cache, then set the body' do
48
+ subject.instance_eval { @template_slug = 'foo' }
49
+ subject.body = 'bar'
50
+ subject.body.should == 'bar'
51
+ subject.instance_eval { @template_slug }.should be_nil
52
+ subject.templates.should == []
53
+ end
54
+ end
55
+
56
+ describe '#templates_join_table_name' do
57
+ it 'should generate the correct join_table, and then apologize for doing so' do
58
+ Page.send(:templates_join_table_name).should == "#{Landable.configuration.database_schema_prefix}landable.page_templates"
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,150 @@
1
+ require 'spec_helper'
2
+
3
+ module Landable::Api
4
+ describe AuditsController, json: true do
5
+ routes { Landable::Engine.routes }
6
+
7
+ let(:page) { create :page }
8
+ let(:template) { create :template }
9
+
10
+ describe '#index' do
11
+ context 'all' do
12
+ include_examples 'Authenticated API controller', :make_request
13
+
14
+ let(:audits) { create_list :audit, 3 }
15
+
16
+ def make_request(params = {})
17
+ get :index
18
+ end
19
+
20
+ it 'renders audits as json' do
21
+ make_request
22
+ last_json['audits'].collect { |p| p['id'] }.sort.should == Landable::Audit.all.map(&:id).sort
23
+ end
24
+ end
25
+
26
+ context 'tempalte audits' do
27
+ include_examples 'Authenticated API controller', :make_request
28
+
29
+ let(:audits) { create_list :audit, 3, auditable_id: template.id, auditable_type: 'Landable::Template', approver: 'ME!!!' }
30
+
31
+ def make_request(params = {})
32
+ get :index, auditable_id: template.id
33
+ end
34
+
35
+ it 'renders audits as json' do
36
+ make_request
37
+ last_json['audits'].collect { |p| p['id'] }.sort.should == Landable::Audit.all.map(&:id).sort
38
+ end
39
+ end
40
+
41
+ context 'page audits' do
42
+ include_examples 'Authenticated API controller', :make_request
43
+
44
+ let(:audits) { create_list :audit, 3, auditable_id: page.id, auditable_type: 'Landable::Page', approver: 'ME!!!' }
45
+
46
+ def make_request(params = {})
47
+ get :index, auditable_id: page.id
48
+ end
49
+
50
+ it 'renders audits as json' do
51
+ make_request
52
+ last_json['audits'].collect { |p| p['id'] }.sort.should == Landable::Audit.all.map(&:id).sort
53
+ end
54
+ end
55
+ end
56
+
57
+ describe '#show' do
58
+ include_examples 'Authenticated API controller', :make_request
59
+ let(:audit) { create(:audit) }
60
+
61
+ def make_request(id = audit.id)
62
+ get :show, id: id
63
+ end
64
+
65
+ it 'renders the page as JSON' do
66
+ make_request
67
+ last_json['audit']['flags'].should == audit.flags
68
+ end
69
+
70
+ context 'no such page' do
71
+ it 'returns 404' do
72
+ make_request random_uuid
73
+ response.status.should == 404
74
+ end
75
+ end
76
+ end
77
+
78
+ describe '#create' do
79
+ context 'template audit' do
80
+ include_examples 'Authenticated API controller', :make_request
81
+
82
+ let(:default_params) do
83
+ { audit: attributes_for(:audit).merge(auditable_id: template.id,
84
+ auditable_type: 'Landable::Template',
85
+ approver: 'Marley') }
86
+ end
87
+
88
+ let(:audit) do
89
+ Landable::Audit.where(auditable_id: default_params[:audit][:auditable_id]).first
90
+ end
91
+
92
+ def make_request(params = {})
93
+ post :create, default_params.deep_merge(audit: params, template_id: template.id)
94
+ end
95
+
96
+ context 'success' do
97
+ it 'returns 201 Created' do
98
+ make_request
99
+ response.status.should == 201
100
+ end
101
+
102
+ it 'returns header Location with the audit URL' do
103
+ make_request
104
+ response.headers['Location'].should == audit_url(audit)
105
+ end
106
+
107
+ it 'renders the audit as JSON' do
108
+ make_request
109
+ last_json['audit']['flags'].should == audit.flags
110
+ end
111
+ end
112
+ end
113
+
114
+ context 'page audit' do
115
+ include_examples 'Authenticated API controller', :make_request
116
+
117
+ let(:default_params) do
118
+ { audit: attributes_for(:audit).merge(auditable_id: page.id,
119
+ auditable_type: 'Landable::Page',
120
+ approver: 'Marley') }
121
+ end
122
+
123
+ let(:audit) do
124
+ Landable::Audit.where(auditable_id: default_params[:audit][:auditable_id]).first
125
+ end
126
+
127
+ def make_request(params = {})
128
+ post :create, default_params.deep_merge(page_audit: params, page_id: page.id)
129
+ end
130
+
131
+ context 'success' do
132
+ it 'returns 201 Created' do
133
+ make_request
134
+ response.status.should == 201
135
+ end
136
+
137
+ it 'returns header Location with the audit URL' do
138
+ make_request
139
+ response.headers['Location'].should == audit_url(audit)
140
+ end
141
+
142
+ it 'renders the audit as JSON' do
143
+ make_request
144
+ last_json['audit']['flags'].should == audit.flags
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ module Landable::Api
4
+ describe ConfigurationsController, json: true do
5
+ routes { Landable::Engine.routes }
6
+
7
+ describe '#show' do
8
+
9
+ def make_request
10
+ get :show
11
+ end
12
+
13
+ it 'renders the page as JSON' do
14
+ make_request
15
+ # defined in Landable Dummy Initalizer
16
+ last_json['configurations'][0]['audit_flags'].should == %w(loans apr)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -13,6 +13,8 @@ Landable.configure do |config|
13
13
  config.reserved_paths = %w(/reserved_path_set_in_initializer /reject/.* /admin.*)
14
14
 
15
15
  config.database_schema_prefix = 'dummy'
16
+
17
+ config.audit_flags = %w(loans apr)
16
18
  end
17
19
 
18
20
  # Configure asset uploads. Assets will be uploaded to public/uploads by default.
@@ -0,0 +1,7 @@
1
+ FactoryGirl.define do
2
+ factory :audit, class: 'Landable::Audit' do
3
+ approver 'Marley Pants'
4
+ notes 'you got served!'
5
+ flags ['loans', 'apr']
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Landable::Audit do
4
+ it { should validate_presence_of(:approver) }
5
+ end
@@ -23,7 +23,7 @@ module Landable
23
23
 
24
24
  describe '#page_id=' do
25
25
  it 'should set page revision attributes matching the page' do
26
- attrs = revision.attributes.except('page_revision_id','ordinal','notes','is_minor','is_published','author_id','created_at','updated_at', 'page_id')
26
+ attrs = revision.attributes.except('page_revision_id','ordinal','notes','is_minor','is_published','author_id','created_at','updated_at', 'page_id', 'audit_flags')
27
27
  attrs.should include(page.attributes.except(*PageRevision.ignored_page_attributes))
28
28
  end
29
29
  end
@@ -57,6 +57,21 @@ module Landable
57
57
  end
58
58
  end
59
59
 
60
+ describe '#republish!' do
61
+ it 'republishes a page revision with almost exact attrs' do
62
+ template = create :template, name: 'Basic'
63
+ old = PageRevision.create!(page_id: page.id, author_id: author.id, is_published: true)
64
+ new_author = create :author
65
+ old.republish!({author_id: new_author.id, notes: "Great Note", template: template.name })
66
+
67
+ new_record = PageRevision.order('created_at ASC').last
68
+ new_record.author_id.should == new_author.id
69
+ new_record.notes.should == "Publishing update for template #{template.name}: Great Note"
70
+ new_record.page_id.should == page.id
71
+ new_record.body.should == page.body
72
+ end
73
+ end
74
+
60
75
  describe '#preview_path' do
61
76
  it 'should return the preview path' do
62
77
  revision.should_receive(:public_preview_page_revision_path) { 'foo' }
@@ -15,7 +15,7 @@ module Landable
15
15
 
16
16
  describe '#template_id=' do
17
17
  it 'should set template revision attributes matching the template' do
18
- attrs = revision.attributes.except('editable', 'is_publishable', 'created_at', 'updated_at', 'published_revision_id', 'file', 'thumbnail_url', 'is_layout', 'is_minor', 'ordinal', 'notes', 'is_published')
18
+ attrs = revision.attributes.except('editable', 'is_publishable', 'created_at', 'updated_at', 'published_revision_id', 'file', 'thumbnail_url', 'is_layout', 'is_minor', 'ordinal', 'notes', 'is_published', 'audit_flags')
19
19
  attrs.should include(template.attributes.except(*TemplateRevision.ignored_template_attributes))
20
20
  end
21
21
  end
@@ -72,6 +72,15 @@ module Landable
72
72
  template.publish! author: author
73
73
  revision1.is_published.should be_false
74
74
  end
75
+
76
+ it 'should call republish_associated_pages' do
77
+ page = create :page
78
+ template.pages = [page]
79
+ template.save!
80
+
81
+ template.should_receive(:republish_associated_pages)
82
+ template.publish! author: author
83
+ end
75
84
  end
76
85
 
77
86
  describe '#revert_to' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: landable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.0.rc1
4
+ version: 1.9.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Team Trogdor
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-12 00:00:00.000000000 Z
11
+ date: 2014-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -309,7 +309,9 @@ files:
309
309
  - app/controllers/concerns/landable/variables_concern.rb
310
310
  - app/controllers/landable/api/access_tokens_controller.rb
311
311
  - app/controllers/landable/api/assets_controller.rb
312
+ - app/controllers/landable/api/audits_controller.rb
312
313
  - app/controllers/landable/api/categories_controller.rb
314
+ - app/controllers/landable/api/configurations_controller.rb
313
315
  - app/controllers/landable/api/directories_controller.rb
314
316
  - app/controllers/landable/api/page_revisions_controller.rb
315
317
  - app/controllers/landable/api/pages_controller.rb
@@ -327,12 +329,14 @@ files:
327
329
  - app/helpers/landable/application_helper.rb
328
330
  - app/helpers/landable/pages_helper.rb
329
331
  - app/models/concerns/landable/has_assets.rb
332
+ - app/models/concerns/landable/has_templates.rb
330
333
  - app/models/concerns/landable/librarian.rb
331
334
  - app/models/concerns/landable/table_name.rb
332
335
  - app/models/concerns/landable/traffic/table_name.rb
333
336
  - app/models/landable/access_token.rb
334
337
  - app/models/landable/asset.rb
335
338
  - app/models/landable/asset_search_engine.rb
339
+ - app/models/landable/audit.rb
336
340
  - app/models/landable/author.rb
337
341
  - app/models/landable/category.rb
338
342
  - app/models/landable/directory.rb
@@ -391,8 +395,10 @@ files:
391
395
  - app/responders/landable/page_render_responder.rb
392
396
  - app/serializers/landable/access_token_serializer.rb
393
397
  - app/serializers/landable/asset_serializer.rb
398
+ - app/serializers/landable/audit_serializer.rb
394
399
  - app/serializers/landable/author_serializer.rb
395
400
  - app/serializers/landable/category_serializer.rb
401
+ - app/serializers/landable/configuration_serializer.rb
396
402
  - app/serializers/landable/directory_serializer.rb
397
403
  - app/serializers/landable/page_revision_serializer.rb
398
404
  - app/serializers/landable/page_serializer.rb
@@ -437,7 +443,9 @@ files:
437
443
  - db/migrate/20140501171359_add_deleted_at_to_assets.rb
438
444
  - db/migrate/20140501171406_add_deleted_at_to_templates.rb
439
445
  - db/migrate/20140509190128_create_template_revisions.rb
446
+ - db/migrate/20140509192856_create_audits.rb
440
447
  - db/migrate/20140515164543_add_screenshot_to_page_revisions.rb
448
+ - db/migrate/20140522202332_join_table_templates_pages.rb
441
449
  - db/migrate/20140602213937_path_response_time_view.rb
442
450
  - db/test/landable.access_tokens.sql
443
451
  - db/test/landable.assets.sql
@@ -450,6 +458,7 @@ files:
450
458
  - db/test/landable.themes.sql
451
459
  - doc/schema/access_token.json
452
460
  - doc/schema/asset.json
461
+ - doc/schema/audit.json
453
462
  - doc/schema/author.json
454
463
  - doc/schema/directory.json
455
464
  - doc/schema/page.json
@@ -530,12 +539,15 @@ files:
530
539
  - script/rails
531
540
  - script/redb
532
541
  - spec/concerns/landable/has_assets_spec.rb
542
+ - spec/concerns/landable/has_templates_spec.rb
533
543
  - spec/concerns/landable/librarian.rb
534
544
  - spec/concerns/landable/table_name_spec.rb
535
545
  - spec/concerns/landable/traffic/table_name_spec.rb
536
546
  - spec/controllers/concerns/landable/variables_concern_spec.rb
537
547
  - spec/controllers/landable/api/assets_controller_spec.rb
548
+ - spec/controllers/landable/api/audits_controller_spec.rb
538
549
  - spec/controllers/landable/api/categories_controller_spec.rb
550
+ - spec/controllers/landable/api/configuration_controller_spec.rb
539
551
  - spec/controllers/landable/api/directories_controller_spec.rb
540
552
  - spec/controllers/landable/api/page_revisions_controller_spec.rb
541
553
  - spec/controllers/landable/api/pages_controller_spec.rb
@@ -583,6 +595,7 @@ files:
583
595
  - spec/dummy/config/locales/en.yml
584
596
  - spec/dummy/config/routes.rb
585
597
  - spec/dummy/db/.keep
598
+ - spec/dummy/db/structure.sql
586
599
  - spec/dummy/lib/assets/.keep
587
600
  - spec/dummy/log/.keep
588
601
  - spec/dummy/public/404.html
@@ -590,6 +603,7 @@ files:
590
603
  - spec/dummy/public/500.html
591
604
  - spec/dummy/public/favicon.ico
592
605
  - spec/factories/asset.rb
606
+ - spec/factories/audit.rb
593
607
  - spec/factories/authors.rb
594
608
  - spec/factories/category.rb
595
609
  - spec/factories/page_revision.rb
@@ -611,6 +625,7 @@ files:
611
625
  - spec/lib/landable/traffic_spec.rb
612
626
  - spec/models/landable/access_token_spec.rb
613
627
  - spec/models/landable/asset_spec.rb
628
+ - spec/models/landable/audit_spec.rb
614
629
  - spec/models/landable/directory_spec.rb
615
630
  - spec/models/landable/page/errors_spec.rb
616
631
  - spec/models/landable/page_revision_spec.rb
@@ -650,7 +665,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
650
665
  version: 1.3.1
651
666
  requirements: []
652
667
  rubyforge_project:
653
- rubygems_version: 2.0.3
668
+ rubygems_version: 2.2.2
654
669
  signing_key:
655
670
  specification_version: 4
656
671
  summary: Mountable CMS engine for Rails
@@ -680,12 +695,15 @@ test_files:
680
695
  - features/support/env.rb
681
696
  - features/support/usefulness.rb
682
697
  - spec/concerns/landable/has_assets_spec.rb
698
+ - spec/concerns/landable/has_templates_spec.rb
683
699
  - spec/concerns/landable/librarian.rb
684
700
  - spec/concerns/landable/table_name_spec.rb
685
701
  - spec/concerns/landable/traffic/table_name_spec.rb
686
702
  - spec/controllers/concerns/landable/variables_concern_spec.rb
687
703
  - spec/controllers/landable/api/assets_controller_spec.rb
704
+ - spec/controllers/landable/api/audits_controller_spec.rb
688
705
  - spec/controllers/landable/api/categories_controller_spec.rb
706
+ - spec/controllers/landable/api/configuration_controller_spec.rb
689
707
  - spec/controllers/landable/api/directories_controller_spec.rb
690
708
  - spec/controllers/landable/api/page_revisions_controller_spec.rb
691
709
  - spec/controllers/landable/api/pages_controller_spec.rb
@@ -733,6 +751,7 @@ test_files:
733
751
  - spec/dummy/config/locales/en.yml
734
752
  - spec/dummy/config/routes.rb
735
753
  - spec/dummy/db/.keep
754
+ - spec/dummy/db/structure.sql
736
755
  - spec/dummy/lib/assets/.keep
737
756
  - spec/dummy/log/.keep
738
757
  - spec/dummy/public/404.html
@@ -740,6 +759,7 @@ test_files:
740
759
  - spec/dummy/public/500.html
741
760
  - spec/dummy/public/favicon.ico
742
761
  - spec/factories/asset.rb
762
+ - spec/factories/audit.rb
743
763
  - spec/factories/authors.rb
744
764
  - spec/factories/category.rb
745
765
  - spec/factories/page_revision.rb
@@ -761,6 +781,7 @@ test_files:
761
781
  - spec/lib/landable/traffic_spec.rb
762
782
  - spec/models/landable/access_token_spec.rb
763
783
  - spec/models/landable/asset_spec.rb
784
+ - spec/models/landable/audit_spec.rb
764
785
  - spec/models/landable/directory_spec.rb
765
786
  - spec/models/landable/page/errors_spec.rb
766
787
  - spec/models/landable/page_revision_spec.rb