exposition 0.0.3.pre.alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +25 -0
- data/app/assets/images/exposition/twitter.svg +10 -0
- data/app/assets/javascripts/exposition/admin/application.js +3 -0
- data/app/assets/stylesheets/exposition/_breakpoints.scss +5 -0
- data/app/assets/stylesheets/exposition/_code.scss +83 -0
- data/app/assets/stylesheets/exposition/_footer.scss +9 -0
- data/app/assets/stylesheets/exposition/_header.scss +62 -0
- data/app/assets/stylesheets/exposition/_layout.scss +28 -0
- data/app/assets/stylesheets/exposition/_mixins.scss +4 -0
- data/app/assets/stylesheets/exposition/_normalize.scss +427 -0
- data/app/assets/stylesheets/exposition/_pagination.scss +18 -0
- data/app/assets/stylesheets/exposition/_posts.scss +96 -0
- data/app/assets/stylesheets/exposition/_tags.scss +12 -0
- data/app/assets/stylesheets/exposition/_variables.scss +16 -0
- data/app/assets/stylesheets/exposition/admin/_layout.scss +58 -0
- data/app/assets/stylesheets/exposition/admin/_mixins.scss +3 -0
- data/app/assets/stylesheets/exposition/admin/_notifications.scss +46 -0
- data/app/assets/stylesheets/exposition/admin/_pagination.scss +12 -0
- data/app/assets/stylesheets/exposition/admin/_posts.scss +7 -0
- data/app/assets/stylesheets/exposition/admin/application.scss +9 -0
- data/app/assets/stylesheets/exposition/admin/base/_base.scss +15 -0
- data/app/assets/stylesheets/exposition/admin/base/_buttons.scss +31 -0
- data/app/assets/stylesheets/exposition/admin/base/_forms.scss +78 -0
- data/app/assets/stylesheets/exposition/admin/base/_grid-settings.scss +14 -0
- data/app/assets/stylesheets/exposition/admin/base/_lists.scss +31 -0
- data/app/assets/stylesheets/exposition/admin/base/_tables.scss +25 -0
- data/app/assets/stylesheets/exposition/admin/base/_typography.scss +55 -0
- data/app/assets/stylesheets/exposition/admin/base/_variables.scss +35 -0
- data/app/assets/stylesheets/exposition/admin/normalize.scss +427 -0
- data/app/assets/stylesheets/exposition/application.scss +17 -0
- data/app/controllers/exposition/admin/admin_controller.rb +5 -0
- data/app/controllers/exposition/admin/posts_controller.rb +5 -0
- data/app/controllers/exposition/admin/sessions_controller.rb +31 -0
- data/app/controllers/exposition/admin/tags_controller.rb +5 -0
- data/app/controllers/exposition/application_controller.rb +8 -0
- data/app/controllers/exposition/posts_controller.rb +5 -0
- data/app/controllers/exposition/tags_controller.rb +5 -0
- data/app/helpers/exposition/admin/flashes_helper.rb +7 -0
- data/app/helpers/exposition/admin/sessions_helper.rb +20 -0
- data/app/helpers/exposition/markdown_helper.rb +21 -0
- data/app/models/categorical/tag.rb +6 -0
- data/app/models/exposition/encryptor.rb +10 -0
- data/app/models/exposition/post.rb +5 -0
- data/app/models/exposition/user.rb +5 -0
- data/app/views/exposition/admin/images/index.html.haml +12 -0
- data/app/views/exposition/admin/images/new.html.haml +0 -0
- data/app/views/exposition/admin/posts/_error_handler.html.haml +8 -0
- data/app/views/exposition/admin/posts/_form_fields.html.haml +23 -0
- data/app/views/exposition/admin/posts/edit.html.haml +5 -0
- data/app/views/exposition/admin/posts/index.html.haml +23 -0
- data/app/views/exposition/admin/posts/new.html.haml +7 -0
- data/app/views/exposition/admin/posts/update.html.haml +2 -0
- data/app/views/exposition/admin/sessions/new.html.haml +10 -0
- data/app/views/exposition/admin/tags/_error_handler.html.haml +8 -0
- data/app/views/exposition/admin/tags/edit.html.haml +10 -0
- data/app/views/exposition/admin/tags/index.html.haml +18 -0
- data/app/views/exposition/admin/tags/new.html.haml +10 -0
- data/app/views/exposition/posts/_post.html.haml +8 -0
- data/app/views/exposition/posts/_tags.html.haml +6 -0
- data/app/views/exposition/posts/index.html.haml +8 -0
- data/app/views/exposition/posts/show.html.haml +5 -0
- data/app/views/exposition/tags/show.html.haml +6 -0
- data/app/views/layouts/exposition/admin.html.haml +22 -0
- data/app/views/layouts/exposition/application.html.haml +20 -0
- data/config/locales/en.yml +37 -0
- data/config/routes.rb +14 -0
- data/db/migrate/20160106220615_create_exposition_posters.rb +12 -0
- data/db/migrate/20160112194424_add_author_id_to_posts.rb +5 -0
- data/db/migrate/20160112200248_create_exposition_users.rb +14 -0
- data/db/migrate/20160112202302_add_slug_to_expositon_posts.rb +7 -0
- data/db/migrate/20160112204019_add_categorial_tags.rb +17 -0
- data/db/migrate/20160225203524_add_summary_to_posts.rb +5 -0
- data/db/migrate/20160226035733_convert_published_at_to_datetime.rb +9 -0
- data/lib/exposition.rb +19 -0
- data/lib/exposition/concerns/controllers/admin/admin_controller.rb +39 -0
- data/lib/exposition/concerns/controllers/admin/posts_controller.rb +70 -0
- data/lib/exposition/concerns/controllers/admin/tags_controller.rb +63 -0
- data/lib/exposition/concerns/controllers/posts_controller.rb +19 -0
- data/lib/exposition/concerns/controllers/tags_controller.rb +31 -0
- data/lib/exposition/concerns/models/post.rb +52 -0
- data/lib/exposition/concerns/models/user.rb +43 -0
- data/lib/exposition/engine.rb +14 -0
- data/lib/exposition/setup.rb +15 -0
- data/lib/exposition/version.rb +3 -0
- data/lib/tasks/exposition_tasks.rake +4 -0
- data/lib/tasks/setup.rb +17 -0
- data/spec/controllers/exposition/admin/admin_controller_spec.rb +88 -0
- data/spec/controllers/exposition/admin/posts_controller_spec.rb +153 -0
- data/spec/controllers/exposition/admin/sessions_controller_spec.rb +46 -0
- data/spec/controllers/exposition/admin/tags_controller_spec.rb +106 -0
- data/spec/controllers/exposition/posts_controller_spec.rb +43 -0
- data/spec/controllers/exposition/tags_controller_spec.rb +40 -0
- data/spec/dummy/Gemfile +5 -0
- data/spec/dummy/Gemfile.lock +173 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/Thorfile +1 -0
- data/spec/dummy/app/assets/javascripts/application.js +1 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +9 -0
- data/spec/dummy/bin/rake +9 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/bin/spring +15 -0
- data/spec/dummy/bin/thor +16 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +26 -0
- data/spec/dummy/config/boot.rb +3 -0
- data/spec/dummy/config/database.yml +12 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/schema.rb +62 -0
- data/spec/dummy/db/seeds.rb +22 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/robots.txt +5 -0
- data/spec/factories/categorical/tags.rb +5 -0
- data/spec/factories/posts.rb +8 -0
- data/spec/factories/taggings.rb +7 -0
- data/spec/factories/users.rb +7 -0
- data/spec/features/admin/post_management_spec.rb +95 -0
- data/spec/features/admin/session_management_spec.rb +40 -0
- data/spec/features/admin/tags_management_spec.rb +59 -0
- data/spec/features/posts_index_spec.rb +28 -0
- data/spec/features/viewing_a_post_spec.rb +21 -0
- data/spec/features/viewing_posts_by_tag_spec.rb +17 -0
- data/spec/helpers/admin/flashes_helper_spec.rb +29 -0
- data/spec/helpers/admin/sessions_helper_spec.rb +56 -0
- data/spec/helpers/markdown_helper_spec.rb +10 -0
- data/spec/models/categorical/tag_spec.rb +35 -0
- data/spec/models/exposition/post_spec.rb +123 -0
- data/spec/models/exposition/user_spec.rb +15 -0
- data/spec/rails_helper.rb +47 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/controllers.rb +6 -0
- data/spec/support/controllers/pagination.rb +17 -0
- data/spec/support/controllers/session_management.rb +20 -0
- data/spec/support/features.rb +6 -0
- data/spec/support/features/pagination.rb +22 -0
- data/spec/support/features/session_management.rb +17 -0
- data/spec/support/models.rb +5 -0
- data/spec/support/models/sluggable.rb +11 -0
- data/spec/tasks/setup_spec.rb +32 -0
- data/spec/views/admin/posts/index.html.haml_spec.rb +16 -0
- metadata +619 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require "rails_helper"
|
|
2
|
+
|
|
3
|
+
RSpec.feature "Posts index page", :type => :feature do
|
|
4
|
+
scenario "a visitor can view published posts" do
|
|
5
|
+
published_post = create(:post, published: true, title: 'Post1')
|
|
6
|
+
unpublished_post = create(:post, published: false, title: 'Post2')
|
|
7
|
+
|
|
8
|
+
visit exposition_path
|
|
9
|
+
|
|
10
|
+
expect(page).to have_text('Post1')
|
|
11
|
+
expect(page).to_not have_text('Post2')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
scenario "a visitor received a notification when there are no posts" do
|
|
15
|
+
visit exposition_path
|
|
16
|
+
|
|
17
|
+
expect(page).to have_text(I18n.t("posts.index.no_posts_warning"))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it do
|
|
21
|
+
paginates(factory: :post,
|
|
22
|
+
increment: 10,
|
|
23
|
+
selector: 'article',
|
|
24
|
+
attributes:{published: true}) do
|
|
25
|
+
visit exposition_path
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require "rails_helper"
|
|
2
|
+
|
|
3
|
+
RSpec.feature "Viewing a post", :type => :feature do
|
|
4
|
+
scenario "a visitor can view published posts" do
|
|
5
|
+
post = create(:post, published: true)
|
|
6
|
+
|
|
7
|
+
visit exposition_path
|
|
8
|
+
click_link(post.title)
|
|
9
|
+
|
|
10
|
+
expect(current_path).to eq(exposition.post_path(post))
|
|
11
|
+
expect(page).to have_text(post.title)
|
|
12
|
+
expect(page).to have_text(post.body)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
scenario "a visitor cannot view unpublished posts" do
|
|
16
|
+
post = create(:post, published: false)
|
|
17
|
+
|
|
18
|
+
expect { visit exposition.post_path(post) }.
|
|
19
|
+
to raise_error(ActiveRecord::RecordNotFound)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require "rails_helper"
|
|
2
|
+
|
|
3
|
+
RSpec.feature "Viewing posts by tag", :type => :feature do
|
|
4
|
+
scenario "a visitor can view published posts by clicking a tag" do
|
|
5
|
+
tag1 = create(:tag, label: 'tag1')
|
|
6
|
+
tag2 = create(:tag, label: 'tag2')
|
|
7
|
+
post1 = create(:post, published: true, title: 'post1', tags: [tag1])
|
|
8
|
+
post2 = create(:post, published: true, title: 'post2', tags: [tag2])
|
|
9
|
+
|
|
10
|
+
visit exposition_path
|
|
11
|
+
click_on 'tag1'
|
|
12
|
+
|
|
13
|
+
expect(current_path).to eq(exposition.tag_path(tag1))
|
|
14
|
+
expect(page).to have_text('post1')
|
|
15
|
+
expect(page).to_not have_text('post2')
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'rails_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Exposition::Admin::FlashesHelper, type: :helper do
|
|
4
|
+
it "converts the the flash into a hash" do
|
|
5
|
+
flash = double("flash")
|
|
6
|
+
allow(flash).to receive(:to_hash).and_return({})
|
|
7
|
+
allow(helper).to receive(:flash).and_return(flash)
|
|
8
|
+
|
|
9
|
+
helper.user_facing_flashes
|
|
10
|
+
|
|
11
|
+
expect(flash).to have_received(:to_hash)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "removes unneeded keys" do
|
|
15
|
+
flash = { "a" => "1",
|
|
16
|
+
"alert" => "2",
|
|
17
|
+
"error" => "3",
|
|
18
|
+
"notice" => "4",
|
|
19
|
+
"success" => "5"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
allow(helper).to receive(:flash).and_return(flash)
|
|
23
|
+
|
|
24
|
+
processed_flash = helper.user_facing_flashes
|
|
25
|
+
|
|
26
|
+
expect(processed_flash).to include("alert")
|
|
27
|
+
expect(processed_flash).to_not include("a")
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'rails_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Exposition::Admin::SessionsHelper, type: :helper do
|
|
4
|
+
describe "#current_user" do
|
|
5
|
+
context "when logged in via a session" do
|
|
6
|
+
it "returns the logged in user" do
|
|
7
|
+
user = create(:user,
|
|
8
|
+
password: 'password',
|
|
9
|
+
email: 'j@j.com',
|
|
10
|
+
name: 'Josh')
|
|
11
|
+
session_params = {user_id: user.id}
|
|
12
|
+
allow(helper).to receive(:session).and_return(session_params)
|
|
13
|
+
|
|
14
|
+
expect(helper.current_user).to eq(user)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
context "when logged in via a cookie" do
|
|
20
|
+
it "returns the logged in user and sets the user_id in the session" do
|
|
21
|
+
user = create(:user,
|
|
22
|
+
password: 'password',
|
|
23
|
+
email: 'j@j.com',
|
|
24
|
+
name: 'Josh')
|
|
25
|
+
user.set_encrypted_remember_token!
|
|
26
|
+
session_params = {}
|
|
27
|
+
signed_cookie_params = {user_id: user.id}
|
|
28
|
+
cookie_params = {remember_token: user.remember_token}
|
|
29
|
+
fake_cookie = FakeCookies.new(
|
|
30
|
+
signed: signed_cookie_params,
|
|
31
|
+
unsigned: cookie_params
|
|
32
|
+
)
|
|
33
|
+
allow(controller).to receive(:cookies).and_return(fake_cookie)
|
|
34
|
+
allow(controller).to receive(:session).and_return(session_params)
|
|
35
|
+
|
|
36
|
+
expect(helper.current_user).to eq(user)
|
|
37
|
+
expect(session_params[:user_id]).to eq(user.id)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class FakeCookies
|
|
42
|
+
def initialize(unsigned:{}, signed:{})
|
|
43
|
+
@signed = signed
|
|
44
|
+
@unsigned = unsigned
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def [](key)
|
|
48
|
+
@unsigned[key]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def signed
|
|
52
|
+
@signed
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require 'rails_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Exposition::MarkdownHelper, type: :helper do
|
|
4
|
+
describe "#markdown_to_html" do
|
|
5
|
+
it "converts markdown into html" do
|
|
6
|
+
expect(helper.markdown_to_html("this *is* really great")).
|
|
7
|
+
to eq("<p>this <em>is</em> really great</p>\n")
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'rails_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Categorical::Tag, type: :model do
|
|
4
|
+
# it_behaves_like "a sluggable"
|
|
5
|
+
|
|
6
|
+
describe "#slug" do
|
|
7
|
+
it "is created automatically from the label if not provided" do
|
|
8
|
+
tag = create(:tag, label: "My Tag")
|
|
9
|
+
|
|
10
|
+
expect(tag.slug).to eq('my-tag')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "is created by user input if provided" do
|
|
14
|
+
tag = create(:tag, label: "My Tag", slug: "my slug")
|
|
15
|
+
|
|
16
|
+
expect(tag.slug).to eq('my-slug')
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe "#to_param" do
|
|
21
|
+
it "returns the slug" do
|
|
22
|
+
tag = build(:tag, slug: 'my-slug')
|
|
23
|
+
|
|
24
|
+
expect(tag.to_param).to eq('my-slug')
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe "#to_s" do
|
|
29
|
+
it "returns the label" do
|
|
30
|
+
tag = build(:tag, label: 'coffee')
|
|
31
|
+
|
|
32
|
+
expect(tag.to_s).to eq('coffee')
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
require 'rails_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Exposition::Post, type: :model do
|
|
4
|
+
it { should have_many(:tags) }
|
|
5
|
+
it { should belong_to(:author).class_name('User') }
|
|
6
|
+
|
|
7
|
+
it { should validate_presence_of(:title) }
|
|
8
|
+
it { should validate_presence_of(:author) }
|
|
9
|
+
it { should validate_length_of(:title).is_at_most(244) }
|
|
10
|
+
it { should validate_presence_of(:body) }
|
|
11
|
+
|
|
12
|
+
describe "#summary" do
|
|
13
|
+
it "offers a the body if no summary is provided" do
|
|
14
|
+
post = build(:post, body: 'This is my body', summary: nil)
|
|
15
|
+
|
|
16
|
+
expect(post.summary).to eq('This is my body')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "give the summary if one is provided" do
|
|
20
|
+
post = build(:post, body: 'This is my body',
|
|
21
|
+
summary: 'This is my summary.')
|
|
22
|
+
|
|
23
|
+
expect(post.summary).to eq('This is my summary.')
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe "#slug" do
|
|
28
|
+
it "is created automatically from the title if not provided" do
|
|
29
|
+
post = create(:post, title: "My Title")
|
|
30
|
+
|
|
31
|
+
expect(post.slug).to eq('my-title')
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "is created user input if provided" do
|
|
35
|
+
post = create(:post, title: "My Title", slug: "my slug")
|
|
36
|
+
|
|
37
|
+
expect(post.slug).to eq('my-slug')
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
describe "#css_classes" do
|
|
42
|
+
it "returns 'not-published' if the article is not published" do
|
|
43
|
+
post = build(:post, published: false)
|
|
44
|
+
|
|
45
|
+
expect(post.css_classes).to eq("not-published")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "returns 'published' if the article is published" do
|
|
49
|
+
post = build(:post, published: true)
|
|
50
|
+
|
|
51
|
+
expect(post.css_classes).to eq("published")
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
describe "#published" do
|
|
56
|
+
it "is false by default" do
|
|
57
|
+
post = build(:post)
|
|
58
|
+
|
|
59
|
+
expect(post.published?).to be_falsey
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
describe ".sorted_by_published_date" do
|
|
64
|
+
it "finds all the published posts ordered by date with the tag" do
|
|
65
|
+
tagged_older_post = create(:post, published: true)
|
|
66
|
+
tagged_newer_post = create(:post, published: true)
|
|
67
|
+
|
|
68
|
+
tagged_older_post.published_at = Time.now - 2.hours
|
|
69
|
+
tagged_newer_post.published_at = Time.now
|
|
70
|
+
tagged_older_post.save!
|
|
71
|
+
tagged_newer_post.save!
|
|
72
|
+
|
|
73
|
+
expect(Exposition::Post.sorted_by_published_date).
|
|
74
|
+
to eq([tagged_newer_post, tagged_older_post])
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe ".published" do
|
|
79
|
+
it "returns only published posts" do
|
|
80
|
+
published_post = create(:post, published: true)
|
|
81
|
+
unpublished_post = create(:post, published: false)
|
|
82
|
+
|
|
83
|
+
expect(Exposition::Post.published).to eq([published_post])
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
describe "#published_at" do
|
|
88
|
+
it "is null by default" do
|
|
89
|
+
post = build(:post)
|
|
90
|
+
|
|
91
|
+
expect(post.published_at).to be_nil
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "is set to the current date when the post is published" do
|
|
95
|
+
post = create(:post)
|
|
96
|
+
|
|
97
|
+
post.published = true
|
|
98
|
+
post.save!
|
|
99
|
+
|
|
100
|
+
expect(post.published_at).to eq(Date.today)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "only updates when the published attribute changes" do
|
|
104
|
+
post = create(:post, published: true)
|
|
105
|
+
|
|
106
|
+
post.published_at = Date.today - 1.day
|
|
107
|
+
post.save!
|
|
108
|
+
|
|
109
|
+
post.published = true
|
|
110
|
+
post.save!
|
|
111
|
+
|
|
112
|
+
expect(post.published_at).to eq(Date.today - 1.day)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
describe "#to_param" do
|
|
117
|
+
it "returns the slug" do
|
|
118
|
+
post = build(:post, slug: 'my-slug')
|
|
119
|
+
|
|
120
|
+
expect(post.to_param).to eq('my-slug')
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'rails_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Exposition::User, type: :model do
|
|
4
|
+
it { should validate_presence_of(:email) }
|
|
5
|
+
it { should validate_presence_of(:name) }
|
|
6
|
+
it { should validate_presence_of(:password) }
|
|
7
|
+
it { should validate_length_of(:name).is_at_most(50) }
|
|
8
|
+
it { should validate_length_of(:email).is_at_most(244) }
|
|
9
|
+
it { should validate_length_of(:password).is_at_least(6) }
|
|
10
|
+
it { should validate_uniqueness_of(:email).case_insensitive }
|
|
11
|
+
it { should allow_value('a@a.com', '12@12.c').for(:email) }
|
|
12
|
+
it { should_not allow_value('a@a', '1', 'a.a').for(:email) }
|
|
13
|
+
it { should have_db_index(:email).unique(true) }
|
|
14
|
+
it { should have_secure_password }
|
|
15
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
|
2
|
+
ENV['RAILS_ENV'] ||= 'test'
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
require File.expand_path('../dummy/config/environment', __FILE__)
|
|
5
|
+
require 'rspec/rails'
|
|
6
|
+
require 'factory_girl_rails'
|
|
7
|
+
require 'database_cleaner'
|
|
8
|
+
require 'shoulda-matchers'
|
|
9
|
+
require 'faker'
|
|
10
|
+
ActiveRecord::Migration.maintain_test_schema!
|
|
11
|
+
|
|
12
|
+
# Adding support files
|
|
13
|
+
# Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
|
14
|
+
Dir[Exposition::Engine.root.join("spec/support/**/*.rb")].each { |f| require f }
|
|
15
|
+
|
|
16
|
+
RSpec.configure do |config|
|
|
17
|
+
config.use_transactional_fixtures = true
|
|
18
|
+
config.infer_spec_type_from_file_location!
|
|
19
|
+
config.include FactoryGirl::Syntax::Methods
|
|
20
|
+
config.use_transactional_fixtures = false
|
|
21
|
+
|
|
22
|
+
config.expect_with :rspec do |expectations|
|
|
23
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
config.mock_with :rspec do |mocks|
|
|
27
|
+
mocks.verify_partial_doubles = true
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
config.before(:suite) do
|
|
31
|
+
DatabaseCleaner.clean_with(:truncation)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
config.before(:each) do |example|
|
|
35
|
+
DatabaseCleaner.strategy= example.metadata[:js] ? :truncation : :transaction
|
|
36
|
+
DatabaseCleaner.start
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
config.after(:each) do
|
|
40
|
+
DatabaseCleaner.clean
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Delete test files from paperclip
|
|
44
|
+
config.after(:suite) do
|
|
45
|
+
FileUtils.rm_rf(Dir["#{Rails.root}/spec/test_files/"])
|
|
46
|
+
end
|
|
47
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'pry-rails'
|
|
2
|
+
|
|
3
|
+
RSpec.configure do |config|
|
|
4
|
+
config.expect_with :rspec do |expectations|
|
|
5
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
config.mock_with :rspec do |mocks|
|
|
9
|
+
mocks.verify_partial_doubles = true
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Controllers
|
|
2
|
+
module Pagination
|
|
3
|
+
def paginates(factory:, increment:)
|
|
4
|
+
factory_string = factory.to_s
|
|
5
|
+
factory = factory_string.underscore.to_sym
|
|
6
|
+
factory_plural = factory_string.pluralize.underscore.to_sym
|
|
7
|
+
number_of_results_for_two_pages = increment + 1
|
|
8
|
+
results =
|
|
9
|
+
FactoryGirl.create_list(factory, number_of_results_for_two_pages)
|
|
10
|
+
|
|
11
|
+
yield
|
|
12
|
+
|
|
13
|
+
expect(assigns(factory_plural).count).to eq(increment)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Controllers
|
|
2
|
+
module SessionManagement
|
|
3
|
+
def create_user_and_login
|
|
4
|
+
user = create(:user)
|
|
5
|
+
fake_login_with(user)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def build_user_and_login
|
|
10
|
+
user = build(:user)
|
|
11
|
+
fake_login_with(user)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def fake_login_with(user)
|
|
15
|
+
allow(controller).to receive(:current_user).and_return(user)
|
|
16
|
+
return user
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|