spontaneous 0.2.0.beta5 → 0.2.0.beta6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +39 -0
- data/Gemfile +2 -0
- data/Readme.markdown +4 -4
- data/application/css/core.css.scss +144 -43
- data/application/css/definitions.css.scss +50 -16
- data/application/css/dialogue.css.scss +5 -2
- data/application/css/editing.css.scss +7 -7
- data/application/css/font.css.scss +1 -1
- data/application/css/meta.css.scss +6 -6
- data/application/css/popover.css.scss +6 -6
- data/application/css/top.css.scss +8 -1
- data/application/js/add_alias_dialogue.js +137 -36
- data/application/js/add_home_dialogue.js +10 -10
- data/application/js/ajax.js +26 -26
- data/application/js/authentication.js +2 -2
- data/application/js/box.js +21 -10
- data/application/js/box_container.js +13 -7
- data/application/js/compatibility.js +19 -17
- data/application/js/conflicted_field_dialogue.js +5 -5
- data/application/js/content.js +22 -16
- data/application/js/content_area.js +62 -33
- data/application/js/dialogue.js +16 -16
- data/application/js/dom.js +9 -10
- data/application/js/edit_panel.js +25 -20
- data/application/js/editing.js +21 -8
- data/application/js/entry.js +1 -1
- data/application/js/extensions.js +11 -11
- data/application/js/field/boolean.js +6 -6
- data/application/js/field/date.js +1 -1
- data/application/js/field/file.js +17 -17
- data/application/js/field/image.js +27 -27
- data/application/js/field/markdown.js +72 -71
- data/application/js/field/select.js +9 -9
- data/application/js/field/string.js +3 -3
- data/application/js/field/webvideo.js +2 -2
- data/application/js/field_preview.js +3 -0
- data/application/js/init.js +3 -2
- data/application/js/jquery-selection-position.js +13 -13
- data/application/js/location.js +17 -12
- data/application/js/login.js +2 -2
- data/application/js/meta_view/user_admin.js +101 -101
- data/application/js/metadata.js +1 -1
- data/application/js/page.js +2 -2
- data/application/js/page_browser.js +13 -13
- data/application/js/page_entry.js +1 -1
- data/application/js/panel/root_menu.js +10 -10
- data/application/js/popover.js +6 -5
- data/application/js/popover_view.js +5 -5
- data/application/js/preview.js +10 -4
- data/application/js/progress.js +6 -6
- data/application/js/properties.js +35 -6
- data/application/js/publish.js +43 -43
- data/application/js/require.js +14 -14
- data/application/js/services.js +3 -3
- data/application/js/sharded_upload.js +9 -8
- data/application/js/side_bar.js +5 -5
- data/application/js/state.js +2 -2
- data/application/js/status_bar.js +6 -6
- data/application/js/top_bar.js +97 -65
- data/application/js/types.js +9 -6
- data/application/js/upload.js +4 -4
- data/application/js/upload_manager.js +21 -21
- data/application/js/user.js +1 -1
- data/application/js/vendor/jquery.velocity.min.js +7 -0
- data/application/js/views.js +32 -8
- data/application/js/views/box_view.js +51 -31
- data/application/js/views/page_piece_view.js +17 -15
- data/application/js/views/page_view.js +54 -43
- data/application/js/views/piece_view.js +44 -37
- data/application/static/font/fontawesome-webfont-4f0022f25672c7f501c339cbf98d9117.ttf +0 -0
- data/application/views/index.erb +1 -0
- data/db/migrations/20130114120000_create_revision_tables.rb +2 -1
- data/db/migrations/20130813111009_increase_path_length.rb +11 -2
- data/db/migrations/20140506171823_add_index_to_target_id.rb +11 -0
- data/db/migrations/20140514090204_add_content_hash.rb +59 -0
- data/db/migrations/20140519150253_add_content_hash_timestamp.rb +20 -0
- data/lib/spontaneous.rb +0 -1
- data/lib/spontaneous/asset/environment.rb +77 -15
- data/lib/spontaneous/box.rb +21 -0
- data/lib/spontaneous/capistrano/deploy.rb +1 -1
- data/lib/spontaneous/capistrano/sync.rb +8 -7
- data/lib/spontaneous/change.rb +4 -2
- data/lib/spontaneous/cli/fields.rb +7 -3
- data/lib/spontaneous/cli/generate.rb +2 -0
- data/lib/spontaneous/cli/init.rb +24 -93
- data/lib/spontaneous/cli/init/db.rb +94 -0
- data/lib/spontaneous/cli/init/mysql.rb +17 -0
- data/lib/spontaneous/cli/init/postgresql.rb +33 -0
- data/lib/spontaneous/cli/init/sqlite.rb +14 -0
- data/lib/spontaneous/cli/site.rb +45 -20
- data/lib/spontaneous/collections/box_set.rb +3 -0
- data/lib/spontaneous/collections/entry_set.rb +43 -4
- data/lib/spontaneous/collections/field_set.rb +14 -2
- data/lib/spontaneous/data_mapper.rb +40 -7
- data/lib/spontaneous/data_mapper/content_model.rb +1 -1
- data/lib/spontaneous/data_mapper/content_model/associations.rb +63 -12
- data/lib/spontaneous/data_mapper/content_model/timestamps.rb +9 -14
- data/lib/spontaneous/data_mapper/content_table.rb +4 -2
- data/lib/spontaneous/data_mapper/dataset.rb +31 -2
- data/lib/spontaneous/data_mapper/scope.rb +37 -20
- data/lib/spontaneous/errors.rb +6 -0
- data/lib/spontaneous/facet.rb +20 -10
- data/lib/spontaneous/field/base.rb +8 -1
- data/lib/spontaneous/field/file.rb +28 -3
- data/lib/spontaneous/field/image.rb +2 -0
- data/lib/spontaneous/field/update.rb +6 -0
- data/lib/spontaneous/field/webvideo/vimeo.rb +6 -1
- data/lib/spontaneous/field/webvideo/vine.rb +1 -1
- data/lib/spontaneous/field/webvideo/youtube.rb +1 -1
- data/lib/spontaneous/generators/site.rb +6 -4
- data/lib/spontaneous/generators/site/.gitignore +1 -0
- data/lib/spontaneous/generators/site/Gemfile.tt +3 -3
- data/lib/spontaneous/generators/site/config/{indexes.rb.tt → initializers/indexes.rb.tt} +0 -0
- data/lib/spontaneous/generators/site/config/initializers/publishing.rb.tt +78 -0
- data/lib/spontaneous/generators/site/{config/database.yml.tt → db/mysql2.yml.tt} +7 -6
- data/lib/spontaneous/generators/site/db/postgres.yml.tt +25 -0
- data/lib/spontaneous/generators/site/db/sqlite3.yml.tt +18 -0
- data/lib/spontaneous/generators/site/public/humans.txt.tt +14 -0
- data/lib/spontaneous/generators/site/templates/layouts/standard.html.cut.tt +51 -0
- data/lib/spontaneous/loader.rb +1 -1
- data/lib/spontaneous/logger.rb +1 -1
- data/lib/spontaneous/media/image/optimizer.rb +1 -1
- data/lib/spontaneous/media/image/processor.rb +11 -2
- data/lib/spontaneous/media/image/renderable.rb +2 -0
- data/lib/spontaneous/model.rb +3 -0
- data/lib/spontaneous/model/box/allowed_types.rb +17 -4
- data/lib/spontaneous/model/core.rb +36 -3
- data/lib/spontaneous/model/core/aliases.rb +5 -2
- data/lib/spontaneous/model/core/boxes.rb +6 -0
- data/lib/spontaneous/model/core/cascading_change.rb +38 -0
- data/lib/spontaneous/model/core/content_hash.rb +171 -0
- data/lib/spontaneous/model/core/entries.rb +0 -19
- data/lib/spontaneous/model/core/fields.rb +11 -0
- data/lib/spontaneous/model/core/modifications.rb +22 -21
- data/lib/spontaneous/model/core/render.rb +3 -0
- data/lib/spontaneous/model/core/serialisation.rb +18 -17
- data/lib/spontaneous/model/page.rb +35 -8
- data/lib/spontaneous/model/page/page_tree.rb +20 -8
- data/lib/spontaneous/model/page/paths.rb +79 -50
- data/lib/spontaneous/model/page/singleton.rb +71 -0
- data/lib/spontaneous/model/page/site_map.rb +2 -1
- data/lib/spontaneous/model/page/site_timestamps.rb +2 -2
- data/lib/spontaneous/model/piece.rb +10 -0
- data/lib/spontaneous/output/context.rb +13 -6
- data/lib/spontaneous/output/format.rb +30 -5
- data/lib/spontaneous/output/helpers/script_helper.rb +8 -0
- data/lib/spontaneous/output/helpers/stylesheet_helper.rb +7 -0
- data/lib/spontaneous/output/renderable.rb +16 -0
- data/lib/spontaneous/output/store.rb +1 -1
- data/lib/spontaneous/output/template/renderer.rb +2 -2
- data/lib/spontaneous/page_piece.rb +25 -1
- data/lib/spontaneous/prototypes/box_prototype.rb +13 -0
- data/lib/spontaneous/prototypes/field_prototype.rb +7 -4
- data/lib/spontaneous/publishing.rb +10 -5
- data/lib/spontaneous/publishing/immediate.rb +32 -349
- data/lib/spontaneous/publishing/pipeline.rb +43 -0
- data/lib/spontaneous/publishing/progress.rb +186 -0
- data/lib/spontaneous/publishing/publish.rb +107 -0
- data/lib/spontaneous/publishing/rerender.rb +17 -0
- data/lib/spontaneous/publishing/revision.rb +53 -18
- data/lib/spontaneous/publishing/simultaneous.rb +1 -1
- data/lib/spontaneous/publishing/steps.rb +154 -0
- data/lib/spontaneous/publishing/steps/activate_revision.rb +45 -0
- data/lib/spontaneous/publishing/steps/archive_old_revisions.rb +22 -0
- data/lib/spontaneous/publishing/steps/base_step.rb +49 -0
- data/lib/spontaneous/publishing/steps/copy_static_files.rb +74 -0
- data/lib/spontaneous/publishing/steps/create_revision_directory.rb +24 -0
- data/lib/spontaneous/publishing/steps/generate_rackup_file.rb +51 -0
- data/lib/spontaneous/publishing/steps/generate_search_indexes.rb +24 -0
- data/lib/spontaneous/publishing/steps/render_revision.rb +69 -0
- data/lib/spontaneous/publishing/steps/write_revision_file.rb +43 -0
- data/lib/spontaneous/rack/back.rb +3 -1
- data/lib/spontaneous/rack/back/alias.rb +9 -8
- data/lib/spontaneous/rack/front.rb +1 -1
- data/lib/spontaneous/rack/middleware.rb +7 -4
- data/lib/spontaneous/rack/middleware/transaction.rb +14 -0
- data/lib/spontaneous/rack/page_controller.rb +23 -8
- data/lib/spontaneous/revision.rb +5 -10
- data/lib/spontaneous/schema.rb +5 -0
- data/lib/spontaneous/server.rb +3 -1
- data/lib/spontaneous/site.rb +17 -10
- data/lib/spontaneous/site/publishing.rb +25 -3
- data/lib/spontaneous/site/state.rb +7 -3
- data/lib/spontaneous/tasks/database.rake +5 -10
- data/lib/spontaneous/utils/database/mysql_dumper.rb +5 -1
- data/lib/spontaneous/version.rb +1 -1
- data/spontaneous.gemspec +4 -3
- data/test/fixtures/example_application/config/initializers/initializer1.rb +1 -0
- data/test/fixtures/example_application/config/initializers/initializer2.rb +1 -0
- data/test/fixtures/example_application/config/initializers/publishing.rb +13 -0
- data/test/fixtures/search/config/{indexes.rb → initializers/indexes.rb} +0 -0
- data/test/fixtures/serialisation/root_hash.yaml.erb +10 -4
- data/test/functional/test_application.rb +10 -0
- data/test/functional/test_back.rb +23 -5
- data/test/functional/test_cli.rb +98 -34
- data/test/functional/test_front.rb +7 -3
- data/test/test_helper.rb +35 -28
- data/test/unit/test_alias.rb +20 -3
- data/test/unit/test_assets.rb +58 -30
- data/test/unit/test_changesets.rb +20 -12
- data/test/unit/test_content_hash.rb +496 -0
- data/test/unit/test_context.rb +28 -1
- data/test/unit/test_controllers.rb +96 -61
- data/test/unit/test_crypt.rb +1 -8
- data/test/unit/test_datamapper.rb +95 -19
- data/test/unit/test_features.rb +1 -4
- data/test/unit/test_fields.rb +61 -12
- data/test/unit/test_generators.rb +39 -2
- data/test/unit/test_images.rb +3 -1
- data/test/unit/test_modifications.rb +224 -219
- data/test/unit/test_output_store.rb +10 -0
- data/test/unit/{test_formats.rb → test_outputs.rb} +75 -6
- data/test/unit/test_page.rb +61 -15
- data/test/unit/test_plugins.rb +2 -42
- data/test/unit/test_publishing_pipeline.rb +1050 -0
- data/test/unit/test_render.rb +30 -0
- data/test/unit/test_revisions.rb +110 -2
- data/test/unit/test_schema.rb +4 -0
- data/test/unit/test_search.rb +1 -1
- data/test/unit/test_serialisation.rb +6 -1
- data/test/unit/test_singletons.rb +159 -0
- data/test/unit/test_site.rb +71 -44
- metadata +140 -86
- data/application/static/font/fontawesome-webfont-1c66a4738b40ef0f6b1abca0ba9a796d.ttf +0 -0
- data/test/unit/test_publishing.rb +0 -330
data/test/unit/test_features.rb
CHANGED
@@ -61,15 +61,12 @@ describe "Features" do
|
|
61
61
|
|
62
62
|
@root = ::Page.create
|
63
63
|
Content.delete_revision(1) rescue nil
|
64
|
-
|
64
|
+
quietly {
|
65
65
|
@site.publish_all
|
66
66
|
}
|
67
67
|
end
|
68
68
|
|
69
69
|
after do
|
70
|
-
# (@all_classes.map { |k| k.name.to_sym }).each { |klass|
|
71
|
-
# Object.send(:remove_const, klass) rescue nil
|
72
|
-
# } rescue nil
|
73
70
|
Content.delete
|
74
71
|
end
|
75
72
|
|
data/test/unit/test_fields.rb
CHANGED
@@ -10,7 +10,7 @@ describe "Fields" do
|
|
10
10
|
@now = Time.now
|
11
11
|
stub_time(@now)
|
12
12
|
Spontaneous::State.delete
|
13
|
-
|
13
|
+
@site.background_mode = :immediate
|
14
14
|
end
|
15
15
|
|
16
16
|
after do
|
@@ -167,6 +167,24 @@ describe "Fields" do
|
|
167
167
|
assert content_class.field_prototypes[:date].field_class < Spontaneous::Field::Date
|
168
168
|
assert content_class.field_prototypes[:chunky].field_class < Spontaneous::Field::String
|
169
169
|
end
|
170
|
+
|
171
|
+
it "assigns the value of the field if the default is a proc" do
|
172
|
+
n = 0
|
173
|
+
f = @content_class.field :dynamic, :default => proc { (n += 1) }
|
174
|
+
f.dynamic_default?.must_equal true
|
175
|
+
instance1 = @content_class.create
|
176
|
+
instance1.dynamic.value.must_equal "1"
|
177
|
+
instance1.reload
|
178
|
+
instance1.dynamic.value.must_equal "1"
|
179
|
+
end
|
180
|
+
|
181
|
+
it "uses a dynamic default value to set the page slug" do
|
182
|
+
n = 0
|
183
|
+
page_class = Class.new(::Page)
|
184
|
+
page_class.field :title, default: proc { (n += 1) }
|
185
|
+
page = page_class.create
|
186
|
+
page.slug.must_equal "1"
|
187
|
+
end
|
170
188
|
end
|
171
189
|
|
172
190
|
describe "Field titles" do
|
@@ -643,6 +661,12 @@ describe "Fields" do
|
|
643
661
|
v.count.must_equal 1
|
644
662
|
end
|
645
663
|
|
664
|
+
it "marks a field as unmodified after save" do
|
665
|
+
@instance.title.value = "one"
|
666
|
+
@instance.save.reload
|
667
|
+
@instance.title.modified?.must_equal false
|
668
|
+
end
|
669
|
+
|
646
670
|
it "have a creation date" do
|
647
671
|
now = Time.now + 1000
|
648
672
|
stub_time(now)
|
@@ -814,7 +838,7 @@ describe "Fields" do
|
|
814
838
|
@field.value = "http://www.youtube.com/watch?v=_0jroAM_pO4&feature=feedrec_grec_index"
|
815
839
|
html = @field.render(:html)
|
816
840
|
html.must_match /^<iframe/
|
817
|
-
html.must_match %r{src="
|
841
|
+
html.must_match %r{src="//www\.youtube\.com/embed/_0jroAM_pO4}
|
818
842
|
html.must_match /width="680"/
|
819
843
|
html.must_match /height="384"/
|
820
844
|
html.must_match /theme=light/
|
@@ -834,7 +858,7 @@ describe "Fields" do
|
|
834
858
|
@field.value = "http://vimeo.com/31836285"
|
835
859
|
html = @field.render(:html)
|
836
860
|
html.must_match /^<iframe/
|
837
|
-
html.must_match %r{src="
|
861
|
+
html.must_match %r{src="//player\.vimeo\.com/video/31836285}
|
838
862
|
html.must_match /width="680"/
|
839
863
|
html.must_match /height="384"/
|
840
864
|
html.must_match /color=ccc/
|
@@ -858,7 +882,7 @@ describe "Fields" do
|
|
858
882
|
json[:"tag"].must_equal "<iframe/>"
|
859
883
|
attr = json[:"attr"]
|
860
884
|
attr.must_be_instance_of(Hash)
|
861
|
-
attr[:"src"].must_match %r{
|
885
|
+
attr[:"src"].must_match %r{^//www\.youtube\.com/embed/_0jroAM_pO4}
|
862
886
|
attr[:"src"].must_match /theme=light/
|
863
887
|
attr[:"src"].must_match /hd=1/
|
864
888
|
attr[:"src"].must_match /fs=1/
|
@@ -898,7 +922,7 @@ describe "Fields" do
|
|
898
922
|
@field.value = "https://vine.co/v/brI7pTPb3qU"
|
899
923
|
embed = @field.render(:html)
|
900
924
|
embed.must_match %r(iframe)
|
901
|
-
embed.must_match %r(src=["']
|
925
|
+
embed.must_match %r(src=["']//vine\.co/v/brI7pTPb3qU/card["'])
|
902
926
|
# Vine videos are square
|
903
927
|
embed.must_match %r(width=["']680["'])
|
904
928
|
embed.must_match %r(height=["']680["'])
|
@@ -946,7 +970,8 @@ describe "Fields" do
|
|
946
970
|
@content_class.fields.location.export(nil)[:type].must_equal "Spontaneous.Field.String"
|
947
971
|
end
|
948
972
|
|
949
|
-
it "
|
973
|
+
it "successfully geolocate an address" do
|
974
|
+
# TODO: use mocking to avoid an external API request to googles geolocation service
|
950
975
|
@field.value = "Cambridge, England"
|
951
976
|
@field.value(:lat).must_equal 52.2053370
|
952
977
|
@field.value(:lng).must_equal 0.1218170
|
@@ -1002,7 +1027,10 @@ describe "Fields" do
|
|
1002
1027
|
end
|
1003
1028
|
|
1004
1029
|
describe "File fields" do
|
1030
|
+
let(:path) { File.expand_path("../../fixtures/images/vimlogo.pdf", __FILE__) }
|
1031
|
+
|
1005
1032
|
before do
|
1033
|
+
assert File.exists?(path), "Test file #{path} does not exist"
|
1006
1034
|
@content_class = Class.new(::Piece)
|
1007
1035
|
@prototype = @content_class.field :file
|
1008
1036
|
@content_class.stubs(:name).returns("ContentClass")
|
@@ -1019,8 +1047,6 @@ describe "Fields" do
|
|
1019
1047
|
end
|
1020
1048
|
|
1021
1049
|
it "copy files to the media folder" do
|
1022
|
-
path = File.expand_path("../../fixtures/images/vimlogo.pdf", __FILE__)
|
1023
|
-
assert File.exists?(path), "Test file #{path} does not exist"
|
1024
1050
|
File.open(path, 'rb') do |file|
|
1025
1051
|
@field.value = {
|
1026
1052
|
:tempfile => file,
|
@@ -1034,8 +1060,6 @@ describe "Fields" do
|
|
1034
1060
|
end
|
1035
1061
|
|
1036
1062
|
it "generate the requisite file metadata" do
|
1037
|
-
path = File.expand_path("../../fixtures/images/vimlogo.pdf", __FILE__)
|
1038
|
-
assert File.exists?(path), "Test file #{path} does not exist"
|
1039
1063
|
File.open(path, 'rb') do |file|
|
1040
1064
|
@field.value = {
|
1041
1065
|
:tempfile => file,
|
@@ -1060,13 +1084,38 @@ describe "Fields" do
|
|
1060
1084
|
end
|
1061
1085
|
|
1062
1086
|
it "copy the given file if passed a path to an existing file" do
|
1063
|
-
path = File.expand_path("../../fixtures/images/vimlogo.pdf", __FILE__)
|
1064
1087
|
@field.value = path
|
1065
1088
|
@field.value.must_match %r{/media/.+/vimlogo.pdf$}
|
1066
1089
|
@field.filename.must_equal "vimlogo.pdf"
|
1067
1090
|
@field.filesize.must_equal 2254
|
1068
1091
|
end
|
1069
1092
|
|
1093
|
+
it "sets the unprocessed value to a JSON encoded array of MD5 hash & filename" do
|
1094
|
+
@field.value = path
|
1095
|
+
@instance.save
|
1096
|
+
@field.unprocessed_value.must_equal ["vimlogo.pdf", "1de7e866d69c2f56b4a3f59ed1c98b74"].to_json
|
1097
|
+
end
|
1098
|
+
|
1099
|
+
it "sets the field hash to the MD5 hash of the file" do
|
1100
|
+
@field.value = path
|
1101
|
+
@field.file_hash.must_equal "1de7e866d69c2f56b4a3f59ed1c98b74"
|
1102
|
+
end
|
1103
|
+
|
1104
|
+
it "sets the original filename of the file" do
|
1105
|
+
@field.value = path
|
1106
|
+
@field.original_filename.must_equal "vimlogo.pdf"
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
it "doesn't set the hash of a file that can't be found" do
|
1110
|
+
@field.value = "/images/nosuchfile.rtf"
|
1111
|
+
@field.file_hash.must_equal ""
|
1112
|
+
end
|
1113
|
+
|
1114
|
+
it "sets the original filename of a file that can't be found" do
|
1115
|
+
@field.value = "/images/nosuchfile.rtf"
|
1116
|
+
@field.original_filename.must_equal "/images/nosuchfile.rtf"
|
1117
|
+
end
|
1118
|
+
|
1070
1119
|
describe "clearing" do
|
1071
1120
|
def assert_file_field_empty
|
1072
1121
|
@field.value.must_equal ''
|
@@ -1648,7 +1697,7 @@ describe "Fields" do
|
|
1648
1697
|
lock = @page.update_locks.first
|
1649
1698
|
lock.field.must_equal field
|
1650
1699
|
lock.content.must_equal @instance
|
1651
|
-
lock.page.must_equal @page
|
1700
|
+
lock.page.reload.must_equal @page.reload
|
1652
1701
|
lock.description.must_match /something\.gif/
|
1653
1702
|
lock.created_at.must_equal @now
|
1654
1703
|
lock.location.must_equal "Field ‘image’ of entry 1 in box ‘instances’"
|
@@ -51,7 +51,7 @@ describe "Generators" do
|
|
51
51
|
%w(development.rb production.rb).each do |f|
|
52
52
|
assert_file_exists(site_root, 'config/environments', f)
|
53
53
|
end
|
54
|
-
%w(back.ru front.ru boot.rb database.yml deploy.rb environment.rb user_levels.yml
|
54
|
+
%w(back.ru front.ru boot.rb database.yml deploy.rb environment.rb user_levels.yml).each do |f|
|
55
55
|
assert_file_exists(site_root, 'config', f)
|
56
56
|
end
|
57
57
|
%w(favicon.ico robots.txt).each do |f|
|
@@ -60,6 +60,7 @@ describe "Generators" do
|
|
60
60
|
%w(standard.html.cut).each do |f|
|
61
61
|
assert_file_exists(site_root, 'templates/layouts', f)
|
62
62
|
end
|
63
|
+
assert_file_exists(site_root, 'config/initializers/indexes.rb')
|
63
64
|
assert_file_exists(site_root, 'schema')
|
64
65
|
assert_file_exists(site_root, 'schema/page.rb')
|
65
66
|
assert File.read(site_root / 'schema/page.rb') =~ /class Page < Content::Page/
|
@@ -101,6 +102,12 @@ describe "Generators" do
|
|
101
102
|
[:development, :test, :production].each do |environment|
|
102
103
|
config[environment][:adapter].must_equal "mysql2"
|
103
104
|
config[environment][:database].must_match /^example_com(_test)?/
|
105
|
+
case environment
|
106
|
+
when :production
|
107
|
+
config[environment][:user].must_equal "example_com"
|
108
|
+
else
|
109
|
+
config[environment][:user].must_equal "root"
|
110
|
+
end
|
104
111
|
# db connections seem to work if you exclude the host
|
105
112
|
config[environment][:host].must_equal "127.0.0.1"
|
106
113
|
end
|
@@ -130,7 +137,7 @@ describe "Generators" do
|
|
130
137
|
config = database_config("example_com")
|
131
138
|
[:development, :test].each do |environment|
|
132
139
|
config[environment][:adapter].must_equal "postgres"
|
133
|
-
config[environment][:user].
|
140
|
+
config[environment][:user].must_equal ENV["USER"]
|
134
141
|
config[environment][:database].must_match /^example_com(_test)?/
|
135
142
|
refute config[environment].key?(:host)
|
136
143
|
end
|
@@ -183,6 +190,36 @@ describe "Generators" do
|
|
183
190
|
end
|
184
191
|
end
|
185
192
|
|
193
|
+
describe "configured for a sqlite database" do
|
194
|
+
let(:args) { ["example.com", "--root=#{@tmp}", "--database=sqlite"] }
|
195
|
+
before do
|
196
|
+
@site_root = File.join(@tmp, 'example_com')
|
197
|
+
generate(:site, *args)
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
it "define the correct adapter" do
|
202
|
+
config = database_config("example_com")
|
203
|
+
[:development, :test, :production].each do |environment|
|
204
|
+
config[environment][:adapter].must_equal "sqlite"
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
it "configure the correct gem" do
|
209
|
+
gemfile = File.read(File.join(@site_root, "Gemfile"))
|
210
|
+
gemfile.must_match /^gem 'sqlite3'/
|
211
|
+
end
|
212
|
+
|
213
|
+
it "setup the right db parameters" do
|
214
|
+
config = database_config("example_com")
|
215
|
+
[:development, :test].each do |environment|
|
216
|
+
config[environment][:database].must_match "db/#{environment}.sqlite3"
|
217
|
+
refute config[environment].key?(:user)
|
218
|
+
refute config[environment].key?(:host)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
186
223
|
|
187
224
|
it "include specified connection params in the generated database config" do
|
188
225
|
site_root = File.join(@tmp, 'example_com')
|
data/test/unit/test_images.rb
CHANGED
@@ -17,6 +17,7 @@ describe "Images" do
|
|
17
17
|
describe "Image fields set using absolute values" do
|
18
18
|
before do
|
19
19
|
@image = S::Field::Image.new(:name => "image")
|
20
|
+
@image.prototype = Spontaneous::Prototypes::FieldPrototype.new(@site.model, :image, :image)
|
20
21
|
end
|
21
22
|
it "accept and not alter URL values" do
|
22
23
|
url = "http://example.com/image.png"
|
@@ -179,7 +180,8 @@ describe "Images" do
|
|
179
180
|
@image.src.must_equal "/media/00234/0010/rose.jpg"
|
180
181
|
@image.original.width.must_equal @image.width
|
181
182
|
@image.original.height.must_equal @image.height
|
182
|
-
|
183
|
+
md5 = Digest::MD5.file(@src_image).hexdigest
|
184
|
+
@image.filepath.must_equal ["rose.jpg", md5].to_json
|
183
185
|
end
|
184
186
|
|
185
187
|
|
@@ -8,7 +8,7 @@ describe "Modifications" do
|
|
8
8
|
before do
|
9
9
|
@now = Time.now
|
10
10
|
@site = setup_site
|
11
|
-
|
11
|
+
Timecop.freeze(@now)
|
12
12
|
|
13
13
|
Content.delete
|
14
14
|
|
@@ -42,6 +42,7 @@ describe "Modifications" do
|
|
42
42
|
end
|
43
43
|
|
44
44
|
after do
|
45
|
+
Timecop.return
|
45
46
|
Object.send(:remove_const, :Page) rescue nil
|
46
47
|
Object.send(:remove_const, :Piece) rescue nil
|
47
48
|
Content.delete
|
@@ -50,28 +51,29 @@ describe "Modifications" do
|
|
50
51
|
|
51
52
|
it "register creation date of all content" do
|
52
53
|
c = Content.create
|
53
|
-
c.created_at
|
54
|
+
(c.created_at - @now).must_be :<=, 1
|
54
55
|
page = Page.create
|
55
|
-
page.created_at
|
56
|
+
(page.created_at - @now).must_be :<=, 1
|
56
57
|
end
|
57
58
|
|
58
59
|
it "update modification date of page when page fields are updated" do
|
59
60
|
now = @now + 100
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
61
|
+
Timecop.freeze(now) do
|
62
|
+
c = Page.first
|
63
|
+
(c.modified_at.to_i - @now.to_i).abs.must_be :<=, 1
|
64
|
+
c.update(title: "changed")
|
65
|
+
(c.modified_at - now).abs.must_be :<=, 1
|
66
|
+
end
|
66
67
|
end
|
67
68
|
|
68
69
|
it "update modification date of path when page visibility is changed" do
|
69
70
|
now = @now + 100
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
71
|
+
Timecop.freeze(now) do
|
72
|
+
c = Page.uid("0")
|
73
|
+
(c.modified_at.to_i - @now.to_i).abs.must_be :<=, 1
|
74
|
+
c.toggle_visibility!
|
75
|
+
(c.modified_at - now).abs.must_be :<=, 1
|
76
|
+
end
|
75
77
|
end
|
76
78
|
|
77
79
|
it "update page timestamps on modification of its box fields" do
|
@@ -79,58 +81,54 @@ describe "Modifications" do
|
|
79
81
|
field :title
|
80
82
|
end
|
81
83
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
84
|
+
Timecop.freeze(@now+3600) do
|
85
|
+
page = Page.first :uid => "0"
|
86
|
+
(page.modified_at.to_i - @now.to_i).abs.must_be :<=, 1
|
87
|
+
page.with_fields.title.value = "updated"
|
88
|
+
page.save.reload
|
89
|
+
page.modified_at.to_i.must_equal @now.to_i + 3600
|
90
|
+
end
|
88
91
|
end
|
89
92
|
|
90
93
|
it "update page timestamps on modification of a piece" do
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
94
|
+
Timecop.freeze(@now+3600) do
|
95
|
+
page = Page.first :uid => "0"
|
96
|
+
(page.modified_at.to_i - @now.to_i).abs.must_be :<=, 1
|
97
|
+
content = page.contents.first
|
98
|
+
content.page.must_equal page
|
99
|
+
content.label = "changed"
|
100
|
+
content.save
|
101
|
+
page.reload
|
102
|
+
page.modified_at.to_i.must_equal @now.to_i + 3600
|
103
|
+
end
|
100
104
|
end
|
101
105
|
|
102
106
|
it "update page timestamps on modification of a piece's box fields" do
|
103
107
|
Piece.box :with_fields do
|
104
108
|
field :title
|
105
109
|
end
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
110
|
+
Timecop.freeze(@now+3600) do
|
111
|
+
page = Page.first :uid => "0"
|
112
|
+
(page.modified_at.to_i - @now.to_i).abs.must_be :<=, 1
|
113
|
+
content = page.contents.first
|
114
|
+
|
115
|
+
content.with_fields.title.value = "updated"
|
116
|
+
content.save
|
117
|
+
page.reload
|
118
|
+
page.modified_at.to_i.must_equal @now.to_i + 3600
|
119
|
+
end
|
115
120
|
end
|
116
121
|
|
117
122
|
it "update page timestamp on addition of piece" do
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
it "not update the parent page's timestamp on addition of a child page yyyy" do
|
129
|
-
stub_time(@now+1000)
|
130
|
-
page = Page.first :uid => "0"
|
131
|
-
page.things << Page.new
|
132
|
-
page.save.reload
|
133
|
-
page.modified_at.to_i.must_equal @now.to_i
|
123
|
+
Timecop.freeze(@now + 3600) do
|
124
|
+
page = Page.first :uid => "0"
|
125
|
+
content = Content[page.contents.first.id]
|
126
|
+
content.things << Piece.new
|
127
|
+
content.save
|
128
|
+
content.modified_at.to_i.must_equal @now.to_i + 3600
|
129
|
+
page.reload
|
130
|
+
page.modified_at.to_i.must_equal @now.to_i + 3600
|
131
|
+
end
|
134
132
|
end
|
135
133
|
|
136
134
|
it "update the parent page's modification time if child pages are re-ordered" do
|
@@ -139,204 +137,209 @@ describe "Modifications" do
|
|
139
137
|
page.things << Page.new(:uid => "0.0.0.1")
|
140
138
|
page.save
|
141
139
|
page = Page.first :uid => "0.0.0"
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
140
|
+
Timecop.freeze(@now + 1000) do
|
141
|
+
child = page.things.first
|
142
|
+
child.update_position(1)
|
143
|
+
page.reload.modified_at.to_i.must_equal @now.to_i + 1000
|
144
|
+
end
|
146
145
|
end
|
147
146
|
|
148
147
|
it "update a page's timestamp on modification of its slug" do
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
it "not update child pages timestamps after changing their parent's slug" do
|
157
|
-
page = Page.first :uid => "0.0.0"
|
158
|
-
modified = page.modified_at.to_i
|
159
|
-
stub_time(@now+1000)
|
160
|
-
page = Page.first :uid => "0"
|
161
|
-
page.slug = "changed"
|
162
|
-
page.save.reload
|
163
|
-
page.modified_at.to_i.must_equal @now.to_i + 1000
|
164
|
-
page = Page.first :uid => "0.0.0"
|
165
|
-
page.modified_at.to_i.must_equal modified
|
148
|
+
Timecop.freeze(@now + 1000) do
|
149
|
+
page = Page.first :uid => "0"
|
150
|
+
page.slug = "changed"
|
151
|
+
page.save.reload
|
152
|
+
page.modified_at.to_i.must_equal @now.to_i + 1000
|
153
|
+
end
|
166
154
|
end
|
167
155
|
|
168
156
|
it "update the pages timestamp if a boxes order is changed" do
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
157
|
+
Timecop.freeze(@now+3600) do
|
158
|
+
page = Page.first :uid => "0"
|
159
|
+
content = Content[page.contents.first.id]
|
160
|
+
content.update_position(1)
|
161
|
+
page.reload.modified_at.to_i.must_equal @now.to_i + 3600
|
162
|
+
end
|
174
163
|
end
|
175
164
|
|
176
165
|
it "update the parent page's modification time if the contents of a piece's box are re-ordered" do
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
166
|
+
Timecop.freeze(@now+3600) do
|
167
|
+
page = Page.first :uid => "0"
|
168
|
+
content = page.things.first.things.first
|
169
|
+
content.update_position(1)
|
170
|
+
page.reload.modified_at.to_i.must_equal @now.to_i + 3600
|
171
|
+
end
|
182
172
|
end
|
183
173
|
|
184
174
|
it "update the parent page's modification date if a piece is deleted" do
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
175
|
+
Timecop.freeze(@now+3600) do
|
176
|
+
page = Page.first :uid => "0"
|
177
|
+
content = Content[page.contents.first.id]
|
178
|
+
content.destroy
|
179
|
+
page.reload.modified_at.to_i.must_equal @now.to_i + 3600
|
180
|
+
end
|
190
181
|
end
|
191
182
|
|
192
183
|
it "update the parent page's modification date if a page is deleted" do
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
184
|
+
Timecop.freeze(@now+3600) do
|
185
|
+
page = Page.first :uid => "0"
|
186
|
+
content = Content[page.things.first.things.first.id]
|
187
|
+
content.destroy
|
188
|
+
page.reload.modified_at.to_i.must_equal @now.to_i + 3600
|
189
|
+
end
|
198
190
|
end
|
199
191
|
|
200
192
|
it "add entry to the list of side effects for a visibility change" do
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
193
|
+
Timecop.freeze(@now+3600) do
|
194
|
+
page = Page.first :uid => "1"
|
195
|
+
old_slug = page.slug
|
196
|
+
page.slug = "changed"
|
197
|
+
page.save
|
198
|
+
page.reload
|
199
|
+
page.pending_modifications.length.must_equal 1
|
200
|
+
mods = page.pending_modifications(:slug)
|
201
|
+
mods.length.must_equal 1
|
202
|
+
mod = mods.first
|
203
|
+
mod.must_be_instance_of Spontaneous::Model::Core::Modifications::SlugModification
|
204
|
+
mod.old_value.must_equal old_slug
|
205
|
+
mod.new_value.must_equal "changed"
|
206
|
+
mod.created_at.to_i.must_equal @now.to_i + 3600
|
207
|
+
end
|
215
208
|
end
|
216
209
|
|
217
210
|
it "serialize page modifications" do
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
211
|
+
Timecop.freeze(@now+3600) do
|
212
|
+
page = Page.first :uid => "1"
|
213
|
+
page.slug = "changed"
|
214
|
+
page.save
|
215
|
+
page.pending_modifications.length.must_equal 1
|
216
|
+
mod = page.pending_modifications(:slug).first
|
217
|
+
page = Page.first :id => page.id
|
218
|
+
page.pending_modifications.length.must_equal 1
|
219
|
+
page.pending_modifications(:slug).first.must_equal mod
|
220
|
+
page.pending_modifications(:slug).first.created_at.to_i.must_equal @now.to_i + 3600
|
221
|
+
end
|
228
222
|
end
|
229
223
|
|
230
224
|
it "concatenate multiple slug modifications together" do
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
225
|
+
Timecop.freeze(@now+3600) do
|
226
|
+
page = Page.first :uid => "1"
|
227
|
+
old_slug = page.slug
|
228
|
+
page.slug = "changed"
|
229
|
+
page.save
|
230
|
+
page.pending_modifications.length.must_equal 1
|
231
|
+
page.slug = "changed-again"
|
232
|
+
page.save
|
233
|
+
mod = page.pending_modifications(:slug).first
|
234
|
+
mod.old_value.must_equal old_slug
|
235
|
+
mod.new_value.must_equal "changed-again"
|
236
|
+
end
|
242
237
|
end
|
243
238
|
|
244
239
|
it "know the number of pages affected by slug modification" do
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
240
|
+
Timecop.freeze(@now+3600) do
|
241
|
+
page = Page.first :uid => "1"
|
242
|
+
page.slug = "changed"
|
243
|
+
page.save
|
244
|
+
mod = page.pending_modifications(:slug).first
|
245
|
+
mod.count.must_equal 4
|
246
|
+
end
|
251
247
|
end
|
252
248
|
|
253
249
|
it "show the number of pages whose visibility is affected in the case of a visibility change" do
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
250
|
+
Timecop.freeze(@now+3600) do
|
251
|
+
page = Page.first :uid => "1"
|
252
|
+
page.hide!
|
253
|
+
page.reload
|
254
|
+
mods = page.pending_modifications(:visibility)
|
255
|
+
mods.length.must_equal 1
|
256
|
+
mod = mods.first
|
257
|
+
mod.count.must_equal 4
|
258
|
+
mod.owner.must_equal page
|
259
|
+
end
|
263
260
|
end
|
264
261
|
|
265
262
|
it "record visibility changes that originate from a content piece" do
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
263
|
+
Timecop.freeze(@now+3600) do
|
264
|
+
page = Page.first :uid => "1"
|
265
|
+
page.things.first.hide!
|
266
|
+
page.reload
|
267
|
+
mods = page.pending_modifications(:visibility)
|
268
|
+
mods.length.must_equal 1
|
269
|
+
mod = mods.first
|
270
|
+
mod.count.must_equal 2
|
271
|
+
mod.owner.must_equal page.things.first
|
272
|
+
end
|
275
273
|
end
|
276
274
|
|
277
275
|
it "show number of pages that are to be deleted in the case of a deletion" do
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
276
|
+
Timecop.freeze(@now+3600) do
|
277
|
+
page = Page.first(:uid => "1")
|
278
|
+
owner = page.owner
|
279
|
+
page.destroy
|
280
|
+
page = Page.first(:uid => "root")
|
281
|
+
mods = page.pending_modifications(:deletion)
|
282
|
+
mod = mods.first
|
283
|
+
# count is number of children of deleted page + 1 (for deleted page)
|
284
|
+
mod.count.must_equal 5
|
285
|
+
mod.owner.must_equal owner.reload
|
286
|
+
end
|
288
287
|
end
|
289
288
|
|
290
289
|
it "show number of pages deleted if piece with pages is deleted" do
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
290
|
+
Timecop.freeze(@now+3600) do
|
291
|
+
page = Page.first(:uid => "1")
|
292
|
+
piece = page.things.first
|
293
|
+
owner = piece.owner
|
294
|
+
piece.destroy
|
295
|
+
page = Page.first(:uid => "1")
|
296
|
+
mods = page.pending_modifications(:deletion)
|
297
|
+
mod = mods.first
|
298
|
+
mod.count.must_equal 2
|
299
|
+
mod.owner.must_equal owner.reload
|
300
|
+
end
|
301
301
|
end
|
302
302
|
|
303
303
|
it "show number of pages deleted if page belonging to piece is deleted" do
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
304
|
+
Timecop.freeze(@now+3600) do
|
305
|
+
page = Page.first(:uid => "1")
|
306
|
+
child = page.things.first.things.first
|
307
|
+
owner = child.owner
|
308
|
+
child.destroy
|
309
|
+
page = Page.first(:uid => "1")
|
310
|
+
mods = page.pending_modifications(:deletion)
|
311
|
+
mod = mods.first
|
312
|
+
mod.count.must_equal 1
|
313
|
+
mod.owner.must_equal owner.reload
|
314
|
+
end
|
314
315
|
end
|
315
316
|
|
316
317
|
it "have an empty modification if the slug has been reverted to original value" do
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
318
|
+
Timecop.freeze(@now+3600) do
|
319
|
+
page = Page.first :uid => "1"
|
320
|
+
old_slug = page.slug
|
321
|
+
page.slug = "changed"
|
322
|
+
page.save
|
323
|
+
page.pending_modifications.length.must_equal 1
|
324
|
+
page.slug = "changed-again"
|
325
|
+
page.save
|
326
|
+
page.slug = old_slug
|
327
|
+
page.save
|
328
|
+
mods = page.reload.pending_modifications(:slug)
|
329
|
+
mods.length.must_equal 0
|
330
|
+
end
|
329
331
|
end
|
330
332
|
|
331
333
|
it "have an empty modification if the visibility has been reverted to original value" do
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
334
|
+
Timecop.freeze(@now+3600) do
|
335
|
+
page = Page.first :uid => "1"
|
336
|
+
page.things.first.hide!
|
337
|
+
page.reload
|
338
|
+
page.things.first.show!
|
339
|
+
page.reload
|
340
|
+
mods = page.pending_modifications(:visibility)
|
341
|
+
mods.length.must_equal 0
|
342
|
+
end
|
340
343
|
end
|
341
344
|
|
342
345
|
describe "during publish" do
|
@@ -613,24 +616,26 @@ describe "Modifications" do
|
|
613
616
|
end
|
614
617
|
|
615
618
|
it "add the editor to any modifications" do
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
619
|
+
Timecop.freeze(@now+3600) do
|
620
|
+
page = Page.first :uid => "1"
|
621
|
+
page.current_editor = @user
|
622
|
+
page.slug = "changed"
|
623
|
+
page.save
|
624
|
+
mod = page.pending_modifications(:slug).first
|
625
|
+
mod.user.must_equal @user
|
626
|
+
end
|
623
627
|
end
|
624
628
|
|
625
629
|
it "persist the user" do
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
630
|
+
Timecop.freeze(@now+3600) do
|
631
|
+
page = Page.first :uid => "1"
|
632
|
+
page.current_editor = @user
|
633
|
+
page.slug = "changed"
|
634
|
+
page.save
|
635
|
+
page = Page.first :uid => "1"
|
636
|
+
mod = page.pending_modifications(:slug).first
|
637
|
+
mod.user.must_equal @user
|
638
|
+
end
|
634
639
|
end
|
635
640
|
end
|
636
641
|
end
|