]> gitweb.mndrdr.org Git - arelpe.git/commitdiff
A base to the test suite
authorAidan Cornelius-Bell <[email protected]>
Sat, 11 Jan 2025 08:03:50 +0000 (18:33 +1030)
committerAidan Cornelius-Bell <[email protected]>
Sat, 11 Jan 2025 08:03:50 +0000 (18:33 +1030)
12 files changed:
Gemfile
Gemfile.lock
test/controllers/pages_controller_test.rb [new file with mode: 0644]
test/controllers/posts_controller_test.rb [new file with mode: 0644]
test/fixtures/files/invalid.json [new file with mode: 0644]
test/fixtures/files/posts.json [new file with mode: 0644]
test/fixtures/pages.yml [new file with mode: 0644]
test/fixtures/posts.yml [new file with mode: 0644]
test/fixtures/users.yml [new file with mode: 0644]
test/models/page_test.rb [new file with mode: 0644]
test/models/post_test.rb [new file with mode: 0644]
test/test_helper.rb

diff --git a/Gemfile b/Gemfile
index 43de942d65baa498855f97dc6a0d5c5eb4175d5a..7fd6a65e5992221aba329bddadefc2440ad1e257 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -24,6 +24,8 @@ gem "dotenv"
 gem "hcaptcha"
 # subscribers
 gem "stripe"
+# Adding this because: ostruct.rb was loaded from the standard library, but will no longer be part of the default gems starting from Ruby 3.5.0.
+gem 'ostruct'
 # Scheduling
 gem "whenever", require: false
 # 2FA
@@ -66,5 +68,6 @@ group :test do
   # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
   gem "capybara"
   gem "selenium-webdriver"
+  gem "rails-controller-testing"
   gem "stripe-ruby-mock", '~> 3.1.0', require: 'stripe_mock'
 end
index 98e89d6d406e8bf1c0a55452f7e010eb4c36ea9a..00aa9c9d3b5d934322888194b25a19f3b071ed98 100644 (file)
@@ -199,6 +199,7 @@ GEM
     nokogiri (1.18.1-x86_64-linux-gnu)
       racc (~> 1.4)
     orm_adapter (0.5.0)
+    ostruct (0.6.1)
     parallel (1.26.3)
     parser (3.3.6.0)
       ast (~> 2.4.1)
@@ -232,6 +233,10 @@ GEM
       activesupport (= 8.0.1)
       bundler (>= 1.15.0)
       railties (= 8.0.1)
+    rails-controller-testing (1.0.5)
+      actionpack (>= 5.0.1.rc1)
+      actionview (>= 5.0.1.rc1)
+      activesupport (>= 5.0.1.rc1)
     rails-dom-testing (2.2.0)
       activesupport (>= 5.0.0)
       minitest
@@ -364,8 +369,10 @@ DEPENDENCIES
   kaminari
   letter_opener
   mysql2 (~> 0.5)
+  ostruct
   puma (>= 5.0)
   rails (~> 8.0.1)
+  rails-controller-testing
   redcarpet
   rouge
   rqrcode
diff --git a/test/controllers/pages_controller_test.rb b/test/controllers/pages_controller_test.rb
new file mode 100644 (file)
index 0000000..e5abe20
--- /dev/null
@@ -0,0 +1,62 @@
+require "test_helper"
+
+class PagesControllerTest < ActionDispatch::IntegrationTest
+  include Devise::Test::IntegrationHelpers
+
+  setup do
+    @admin = users(:admin) # You'll need to set up this fixture
+    @page = pages(:one)    # You'll need to set up this fixture
+    sign_in @admin
+  end
+
+  test "should get index" do
+    get pages_url
+    assert_response :success
+  end
+
+  test "should get new" do
+    get new_page_url
+    assert_response :success
+  end
+
+  test "should create page" do
+    assert_difference("Page.count") do
+      post pages_url, params: {
+        page: {
+          title: "New Page",
+          content: "New content",
+          visibility: "visible"
+        }
+      }
+    end
+
+    assert_redirected_to page_url(Page.last)
+  end
+
+  test "should show page" do
+    get page_url(@page)
+    assert_response :success
+  end
+
+  test "should get edit" do
+    get edit_page_url(@page)
+    assert_response :success
+  end
+
+  test "should update page" do
+    patch page_url(@page), params: {
+      page: {
+        title: "Updated Title"
+      }
+    }
+    assert_redirected_to page_url(@page)
+  end
+
+  test "should destroy page" do
+    assert_difference("Page.count", -1) do
+      delete page_url(@page)
+    end
+
+    assert_redirected_to pages_url
+  end
+end
diff --git a/test/controllers/posts_controller_test.rb b/test/controllers/posts_controller_test.rb
new file mode 100644 (file)
index 0000000..ba22759
--- /dev/null
@@ -0,0 +1,102 @@
+require "test_helper"
+
+class PostsControllerTest < ActionDispatch::IntegrationTest
+  include Devise::Test::IntegrationHelpers
+
+  setup do
+    @admin = users(:admin)     # You'll need to set up this fixture
+    @post = posts(:dispatch)   # You'll need to set up this fixture
+    sign_in @admin
+  end
+
+  test "should get index" do
+    get posts_url
+    assert_response :success
+  end
+
+  test "should get new" do
+    get new_post_url
+    assert_response :success
+  end
+
+  test "should create dispatch post" do
+    assert_difference("Post.count") do
+      post posts_url, params: {
+        post: {
+          title: "New Dispatch",
+          content: "Test content",
+          post_type: "dispatch",
+          published_at: Time.current
+        }
+      }
+    end
+
+    assert_redirected_to post_url(Post.last)
+  end
+
+  test "should create bookmark post" do
+    assert_difference("Post.count") do
+      post posts_url, params: {
+        post: {
+          title: "New Bookmark",
+          url: "https://example.com",
+          post_type: "bookmark"
+        }
+      }
+    end
+
+    assert_redirected_to post_url(Post.last)
+  end
+
+  test "should show post" do
+    get post_url(@post)
+    assert_response :success
+  end
+
+  test "should get edit" do
+    get edit_post_url(@post)
+    assert_response :success
+  end
+
+  test "should update post" do
+    patch post_url(@post), params: {
+      post: {
+        title: "Updated Title"
+      }
+    }
+    assert_redirected_to post_url(@post)
+  end
+
+  test "should destroy post" do
+    assert_difference("Post.count", -1) do
+      delete post_url(@post)
+    end
+
+    assert_redirected_to posts_url
+  end
+
+  test "should export posts" do
+    get export_url
+    assert_response :success
+    assert_equal "application/json", response.content_type
+  end
+
+  test "should get importer page" do
+    get importer_url
+    assert_response :success
+  end
+
+  test "should import json file" do
+    file = fixture_file_upload('posts.json', 'application/json')
+    post import_url, params: { file: file }
+    assert_redirected_to posts_url
+    assert_not_nil flash[:notice]
+  end
+
+  test "should handle invalid import file" do
+    file = fixture_file_upload('invalid.json', 'application/json')
+    post import_url, params: { file: file }
+    assert_redirected_to posts_url
+    assert_not_nil flash[:alert]
+  end
+end
diff --git a/test/fixtures/files/invalid.json b/test/fixtures/files/invalid.json
new file mode 100644 (file)
index 0000000..3848732
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  invalid json content
+}
diff --git a/test/fixtures/files/posts.json b/test/fixtures/files/posts.json
new file mode 100644 (file)
index 0000000..da516e6
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "posts": [
+    {
+      "title": "Imported Post",
+      "content": "This is an imported post",
+      "post_type": "dispatch",
+      "published_at": "2024-01-01T12:00:00Z"
+    }
+  ]
+}
diff --git a/test/fixtures/pages.yml b/test/fixtures/pages.yml
new file mode 100644 (file)
index 0000000..485de4b
--- /dev/null
@@ -0,0 +1,11 @@
+one:
+  title: Sample Page
+  slug: sample-page
+  content: This is a sample page content
+  visibility: visible
+
+two:
+  title: Another Page
+  slug: another-page
+  content: This is another page content
+  visibility: hidden
diff --git a/test/fixtures/posts.yml b/test/fixtures/posts.yml
new file mode 100644 (file)
index 0000000..14d7368
--- /dev/null
@@ -0,0 +1,13 @@
+dispatch:
+  title: Sample Dispatch
+  slug: sample-dispatch
+  content: This is a sample dispatch post
+  post_type: dispatch
+  published_at: <%= Time.current %>
+
+bookmark:
+  title: Sample Bookmark
+  slug: sample-bookmark
+  url: https://example.com
+  post_type: bookmark
+  published_at: <%= Time.current %>
diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml
new file mode 100644 (file)
index 0000000..96d8246
--- /dev/null
@@ -0,0 +1,7 @@
+admin:
+  email: [email protected]
+  encrypted_password: <%= User.new.send(:password_digest, 'password123') %>
+  first_name: Admin
+  last_name: User
+  admin: true
+  confirmed_at: <%= Time.current %>
diff --git a/test/models/page_test.rb b/test/models/page_test.rb
new file mode 100644 (file)
index 0000000..489eb5b
--- /dev/null
@@ -0,0 +1,52 @@
+require "test_helper"
+
+class PageTest < ActiveSupport::TestCase
+  def setup
+    @page = Page.new(
+      title: "About Us",
+      content: "Welcome to our site",
+      visibility: "visible"
+    )
+  end
+
+  test "should be valid with valid attributes" do
+    assert @page.valid?
+  end
+
+  test "should require a title" do
+    @page.title = nil
+    assert_not @page.valid?
+    assert_includes @page.errors[:title], "can't be blank"
+  end
+
+  test "should automatically generate slug from title" do
+    @page.slug = nil
+    @page.valid?
+    assert_equal "about-us", @page.slug
+  end
+
+  test "should enforce unique slugs" do
+    @page.save!
+    duplicate_page = Page.new(
+      title: "About Us",
+      content: "Different content",
+      visibility: "visible"
+    )
+    assert_not duplicate_page.valid?
+    assert_includes duplicate_page.errors[:slug], "has already been taken"
+  end
+
+  test "should validate slug format" do
+    @page.slug = "Invalid Slug!"
+    assert_not @page.valid?
+    assert_includes @page.errors[:slug], "can only contain lowercase letters, numbers, and hyphens"
+  end
+
+  test "should have valid visibility values" do
+    valid_visibilities = ['hidden', 'visible', 'user_only', 'admin_only']
+    valid_visibilities.each do |visibility|
+      @page.visibility = visibility
+      assert @page.valid?, "#{visibility} should be valid"
+    end
+  end
+end
diff --git a/test/models/post_test.rb b/test/models/post_test.rb
new file mode 100644 (file)
index 0000000..dc639c1
--- /dev/null
@@ -0,0 +1,100 @@
+require "test_helper"
+
+class PostTest < ActiveSupport::TestCase
+  def setup
+    @dispatch = Post.new(
+      title: "Test Dispatch",
+      content: "Test content",
+      post_type: "dispatch",
+      published_at: Time.current
+    )
+
+    @bookmark = Post.new(
+      title: "Test Bookmark",
+      url: "https://example.com",
+      post_type: "bookmark",
+      published_at: Time.current
+    )
+  end
+
+  test "should be valid with valid dispatch attributes" do
+    assert @dispatch.valid?
+  end
+
+  test "should be valid with valid bookmark attributes" do
+    assert @bookmark.valid?
+  end
+
+  test "should require post_type" do
+    @dispatch.post_type = nil
+    assert_not @dispatch.valid?
+    assert_includes @dispatch.errors[:post_type], "can't be blank"
+  end
+
+  test "should only allow valid post types" do
+    @dispatch.post_type = "invalid"
+    assert_not @dispatch.valid?
+    assert_includes @dispatch.errors[:post_type], "is not included in the list"
+  end
+
+  test "should require content for dispatch posts" do
+    @dispatch.content = nil
+    assert_not @dispatch.valid?
+    assert_includes @dispatch.errors[:content], "can't be blank"
+  end
+
+  test "should require url for bookmark posts" do
+    @bookmark.url = nil
+    assert_not @bookmark.valid?
+    assert_includes @bookmark.errors[:url], "can't be blank"
+  end
+
+  test "should handle duplicate slugs" do
+      # Create first post
+      first_post = Post.create!(
+        title: "Test Post",
+        content: "Original content",
+        post_type: "dispatch",
+        published_at: Time.current
+      )
+
+      # Create second post with same title but modified slug
+      second_post = Post.create!(
+        title: "Test Post",
+        content: "Different content",
+        post_type: "dispatch",
+        published_at: Time.current,
+        slug: "test-post-1"  # Manually set a unique slug
+      )
+
+      # Verify posts have different slugs
+      assert_not_equal first_post.slug, second_post.slug
+      assert_equal "test-post", first_post.slug
+      assert_equal "test-post-1", second_post.slug
+  end
+
+  test "should generate excerpt" do
+    @dispatch.content = "This is a test post with multiple sentences. This is the second sentence."
+    assert_equal "This is a test post with multiple sentences", @dispatch.generate_excerpt
+  end
+
+  test "should identify short dispatches" do
+    @dispatch.content = "Short content"
+    assert @dispatch.short_dispatch?
+
+    @dispatch.content = "Dear friends, " + "word " * 150
+    assert_not @dispatch.short_dispatch?
+  end
+
+  test "should format tags" do
+    @dispatch.tags = "ruby, rails"
+    assert_equal "<code>ruby</code>, <code>rails</code>.", @dispatch.format_tags
+  end
+
+  test "should generate slug from url for bookmarks without title" do
+    @bookmark.title = nil
+    @bookmark.url = "https://example.com/page"
+    @bookmark.valid?
+    assert_match /^example-com-\d{14}$/, @bookmark.slug
+  end
+end
index 9c9ba956dcde851a2eb36b7c55038b3b758fff98..b99ca9047697966e1603023db7d491914c4ee34d 100644 (file)
@@ -1,7 +1,20 @@
-require "test_helper"
+ENV["RAILS_ENV"] ||= "test"
+require "dotenv"
+Dotenv.load(".env.test")
 
-class ArticleTest < ActiveSupport::TestCase
-  # test "the truth" do
-  #   assert true
-  # end
+require_relative "../config/environment"
+require "rails/test_help"
+
+class ActiveSupport::TestCase
+  # Run tests in parallel with specified workers
+  parallelize(workers: :number_of_processors) unless ENV["PARALLEL_WORKERS"] == "1"
+
+  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order
+  fixtures :all
+
+  # Add more helper methods to be used by all tests here...
+end
+
+class ActionDispatch::IntegrationTest
+  include Devise::Test::IntegrationHelpers
 end