Merge branch 'master' into skeb

This commit is contained in:
evazion
2021-03-08 03:43:15 -06:00
committed by GitHub
91 changed files with 840 additions and 438 deletions

View File

@@ -46,8 +46,8 @@ class PostNavbarComponentTest < ViewComponent::TestCase
context "for a post with favgroups" do
setup do
as(@user) do
@favgroup1 = create(:favorite_group, creator: @user)
@favgroup2 = create(:favorite_group, creator: @user)
@favgroup1 = create(:favorite_group, creator: @user, is_public: true)
@favgroup2 = create(:favorite_group, creator: @user, is_public: false)
@post.update(tag_string: "favgroup:#{@favgroup1.id} favgroup:#{@favgroup2.id}")
end
end
@@ -65,6 +65,18 @@ class PostNavbarComponentTest < ViewComponent::TestCase
assert_css(".favgroup-navbar[data-selected=true] .favgroup-name", text: "Favgroup: #{@favgroup1.pretty_name}")
assert_css(".favgroup-navbar[data-selected=false] .favgroup-name", text: "Favgroup: #{@favgroup2.pretty_name}")
end
should "show public favgroups that belong to another user when doing a favgroup:<id> search" do
render_post_navbar(@post, current_user: create(:user), search: "favgroup:#{@favgroup1.id}")
assert_css(".favgroup-navbar[data-selected=true] .favgroup-name", text: "Favgroup: #{@favgroup1.pretty_name}")
end
should "not show private favgroups that belong to another user when doing a favgroup:<id> search" do
render_post_navbar(@post, current_user: create(:user), search: "favgroup:#{@favgroup2.id}")
assert_css(".favgroup-navbar .favgroup-name", count: 0)
end
end
end
end

View File

@@ -0,0 +1,8 @@
FactoryBot.define do
factory(:rate_limit) do
limited { false }
points { 0 }
action { "test" }
key { "1234" }
end
end

View File

@@ -227,7 +227,7 @@ class ApplicationControllerTest < ActionDispatch::IntegrationTest
should "fail with a 429 error" do
user = create(:user)
post = create(:post, rating: "s")
TokenBucket.any_instance.stubs(:throttled?).returns(true)
RateLimit.any_instance.stubs(:limited?).returns(true)
put_auth post_path(post), user, params: { post: { rating: "e" } }

View File

@@ -100,6 +100,11 @@ class BansControllerTest < ActionDispatch::IntegrationTest
assert_response :success
end
end
should "not raise an exception on a blank username" do
post_auth bans_path, @mod, params: {}
assert_response :success
end
end
context "update action" do

View File

@@ -142,14 +142,14 @@ class CommentsControllerTest < ActionDispatch::IntegrationTest
context "when updating another user's comment" do
should "succeed if updater is a moderator" do
put_auth comment_path(@comment.id), @user, params: {comment: {body: "abc"}}
put_auth comment_path(@comment.id), @user, params: {comment: {body: "abc"}}, xhr: true
assert_equal("abc", @comment.reload.body)
assert_redirected_to post_path(@comment.post)
assert_response :success
end
should "fail if updater is not a moderator" do
@mod_comment = as(@mod) { create(:comment, post: @post) }
put_auth comment_path(@mod_comment.id), @user, params: {comment: {body: "abc"}}
put_auth comment_path(@mod_comment.id), @user, params: {comment: {body: "abc"}}, xhr: true
assert_not_equal("abc", @mod_comment.reload.body)
assert_response 403
end
@@ -157,13 +157,13 @@ class CommentsControllerTest < ActionDispatch::IntegrationTest
context "when stickying a comment" do
should "succeed if updater is a moderator" do
put_auth comment_path(@comment.id), @mod, params: {comment: {is_sticky: true}}
put_auth comment_path(@comment.id), @mod, params: {comment: {is_sticky: true}}, xhr: true
assert_equal(true, @comment.reload.is_sticky)
assert_redirected_to @comment.post
assert_response :success
end
should "fail if updater is not a moderator" do
put_auth comment_path(@comment.id), @user, params: {comment: {is_sticky: true}}
put_auth comment_path(@comment.id), @user, params: {comment: {is_sticky: true}}, xhr: true
assert_response 403
assert_equal(false, @comment.reload.is_sticky)
end
@@ -172,7 +172,7 @@ class CommentsControllerTest < ActionDispatch::IntegrationTest
context "for a deleted comment" do
should "not allow the creator to edit the comment" do
@comment.update!(is_deleted: true)
put_auth comment_path(@comment.id), @user, params: { comment: { body: "blah" }}
put_auth comment_path(@comment.id), @user, params: { comment: { body: "blah" }}, xhr: true
assert_response 403
assert_not_equal("blah", @comment.reload.body)
@@ -180,16 +180,16 @@ class CommentsControllerTest < ActionDispatch::IntegrationTest
end
should "update the body" do
put_auth comment_path(@comment.id), @user, params: {comment: {body: "abc"}}
put_auth comment_path(@comment.id), @user, params: {comment: {body: "abc"}}, xhr: true
assert_equal("abc", @comment.reload.body)
assert_redirected_to post_path(@comment.post)
assert_response :success
end
should "allow changing the body and is_deleted" do
put_auth comment_path(@comment.id), @user, params: {comment: {body: "herp derp", is_deleted: true}}
put_auth comment_path(@comment.id), @user, params: {comment: {body: "herp derp", is_deleted: true}}, xhr: true
assert_equal("herp derp", @comment.reload.body)
assert_equal(true, @comment.is_deleted)
assert_redirected_to post_path(@post)
assert_response :success
end
should "not allow changing do_not_bump_post or post_id" do

View File

@@ -0,0 +1,33 @@
require 'test_helper'
class RateLimitsControllerTest < ActionDispatch::IntegrationTest
context "The rate limits controller" do
context "index action" do
setup do
@user = create(:user)
create(:rate_limit, key: @user.cache_key)
end
should "show all rate limits to the owner" do
get_auth rate_limits_path, create(:owner_user)
assert_response :success
assert_select "tbody tr", count: 2 # 2 because the login action creates a second rate limit.
end
should "show the user their own rate limits" do
get_auth rate_limits_path, @user
assert_response :success
assert_select "tbody tr", count: 1
end
should "not show users rate limits belonging to other users" do
get_auth rate_limits_path, create(:user)
assert_response :success
assert_select "tbody tr", count: 0
end
end
end
end

View File

@@ -72,6 +72,31 @@ class SessionsControllerTest < ActionDispatch::IntegrationTest
assert_equal(0, @ip_ban.reload.hit_count)
assert_nil(@ip_ban.last_hit_at)
end
should "rate limit logins to 10 per minute per IP" do
freeze_time
11.times do
post session_path, params: { name: @user.name, password: "password" }, headers: { REMOTE_ADDR: "1.2.3.4" }
assert_redirected_to posts_path
assert_equal(@user.id, session[:user_id])
delete_auth session_path, @user
end
post session_path, params: { name: @user.name, password: "password" }, headers: { REMOTE_ADDR: "1.2.3.4" }
assert_response 429
assert_not_equal(@user.id, session[:user_id])
travel 59.seconds
post session_path, params: { name: @user.name, password: "password" }, headers: { REMOTE_ADDR: "1.2.3.4" }
assert_response 429
assert_not_equal(@user.id, session[:user_id])
travel 10.seconds
post session_path, params: { name: @user.name, password: "password" }, headers: { REMOTE_ADDR: "1.2.3.4" }
assert_redirected_to posts_path
assert_equal(@user.id, session[:user_id])
end
end
context "destroy action" do

View File

@@ -48,11 +48,5 @@ class ApiKeyTest < ActiveSupport::TestCase
should "not authenticate with the wrong name" do
assert_equal(false, create(:user).authenticate_api_key(@api_key.key))
end
should "have the same limits whether or not they have an api key" do
assert_no_difference(["@user.reload.api_regen_multiplier", "@user.reload.api_burst_limit"]) do
@api_key.destroy
end
end
end
end

View File

@@ -33,7 +33,7 @@ class IpGeolocationTest < ActiveSupport::TestCase
should "work for a residential IP" do
@ip = IpGeolocation.create_or_update!("2a01:0e35:2f22:e3d0::1")
assert_equal(26, @ip.network.prefix)
assert_equal(28, @ip.network.prefix)
assert_equal(false, @ip.is_proxy?)
assert_equal(49, @ip.latitude.round(0))
assert_equal(2, @ip.longitude.round(0))

View File

@@ -0,0 +1,72 @@
require 'test_helper'
class RateLimitTest < ActiveSupport::TestCase
context "RateLimit: " do
context "#limit! method" do
should "create a new rate limit object if none exists, or update it if it already exists" do
assert_difference("RateLimit.count", 1) do
RateLimiter.new("write", ["users/1"]).limited?
end
assert_difference("RateLimit.count", 0) do
RateLimiter.new("write", ["users/1"]).limited?
end
assert_difference("RateLimit.count", 1) do
RateLimiter.new("write", ["users/1", "ip/1.2.3.4"]).limited?
end
assert_difference("RateLimit.count", 0) do
RateLimiter.new("write", ["users/1", "ip/1.2.3.4"]).limited?
end
end
should "include the cost of the first action when initializing the limit" do
limiter = RateLimiter.new("write", ["users/1"], burst: 10, cost: 1)
assert_equal(9, limiter.rate_limits.first.points)
end
should "be limited and penalize the caller 1 second if the point count is negative" do
freeze_time
create(:rate_limit, action: "write", key: "users/1", points: -1)
limiter = RateLimiter.new("write", ["users/1"], cost: 1)
assert_equal(true, limiter.limited?)
assert_equal(-2, limiter.rate_limits.first.points)
end
should "not be limited if the point count was positive before the action" do
freeze_time
create(:rate_limit, action: "write", key: "users/1", points: 0.01)
limiter = RateLimiter.new("write", ["users/1"], cost: 1)
assert_equal(false, limiter.limited?)
assert_equal(-0.99, limiter.rate_limits.first.points)
end
should "refill the points at the correct rate" do
freeze_time
create(:rate_limit, action: "write", key: "users/1", points: -2)
limiter = RateLimiter.new("write", ["users/1"], cost: 1, rate: 1, burst: 10)
assert_equal(true, limiter.limited?)
assert_equal(-3, limiter.rate_limits.first.points)
travel 1.second
limiter = RateLimiter.new("write", ["users/1"], cost: 1, rate: 1, burst: 10)
assert_equal(true, limiter.limited?)
assert_equal(-3, limiter.rate_limits.first.points)
travel 5.second
limiter = RateLimiter.new("write", ["users/1"], cost: 1, rate: 1, burst: 10)
assert_equal(false, limiter.limited?)
assert_equal(1, limiter.rate_limits.first.points)
travel 60.second
limiter = RateLimiter.new("write", ["users/1"], cost: 1, rate: 1, burst: 10)
assert_equal(false, limiter.limited?)
assert_equal(9, limiter.rate_limits.first.points)
end
end
end
end

View File

@@ -95,20 +95,30 @@ module Sources
should "fetch the source data" do
assert_equal("evazion", @site.artist_name)
end
should "correctly get the page url" do
assert_equal(@ref, @site.page_url)
end
end
context "A baraag url" do
setup do
skip "Baraag keys not set" unless Danbooru.config.baraag_client_id
@url = "https://baraag.net/@bardbot/105732813175612920"
@site = Sources::Strategies.find(@url)
@site1 = Sources::Strategies.find(@url)
@img = "https://baraag.net/system/media_attachments/files/105/803/948/862/719/091/original/54e1cb7ca33ec449.png"
@ref = "https://baraag.net/@Nakamura/105803949565505009"
@site2 = Sources::Strategies.find(@img, @ref)
end
should "work" do
assert_equal("https://baraag.net/@bardbot", @site.profile_url)
assert_equal(["https://baraag.net/system/media_attachments/files/105/732/803/241/495/700/original/556e1eb7f5ca610f.png"], @site.image_urls)
assert_equal("bardbot", @site.artist_name)
assert_equal("🍌", @site.dtext_artist_commentary_desc)
assert_equal("https://baraag.net/@bardbot", @site1.profile_url)
assert_equal(["https://baraag.net/system/media_attachments/files/105/732/803/241/495/700/original/556e1eb7f5ca610f.png"], @site1.image_urls)
assert_equal("bardbot", @site1.artist_name)
assert_equal("🍌", @site1.dtext_artist_commentary_desc)
assert_equal([@img], @site2.image_urls)
end
end

View File

@@ -305,6 +305,18 @@ module Sources
end
end
context "when the cached session cookie is invalid" do
should "clear the cached cookie after failing to fetch the data" do
site = Sources::Strategies.find("https://nijie.info/view.php?id=203688")
Cache.put("nijie-session-cookie", HTTP::Cookie.new(name: "NIJIEIJIEID", value: "fake", domain: "nijie.info", path: "/"))
assert_equal("fake", site.cached_session_cookie.value)
assert_equal([], site.image_urls)
assert_nil(Cache.get("nijie-session-cookie"))
end
end
context "a doujin post" do
should "work" do
image = "https://pic.nijie.net/01/dojin_main/dojin_sam/20120213044700%E3%82%B3%E3%83%94%E3%83%BC%20%EF%BD%9E%200011%E3%81%AE%E3%82%B3%E3%83%94%E3%83%BC.jpg"

View File

@@ -1,45 +0,0 @@
require 'test_helper'
class TokenBucketTest < ActiveSupport::TestCase
context "#add!" do
setup do
@user = FactoryBot.create(:user)
TokenBucket.create(user_id: @user.id, last_touched_at: 1.minute.ago, token_count: 0)
end
should "work" do
@user.token_bucket.add!
assert_operator(@user.token_bucket.token_count, :>, 0)
@user.reload
assert_operator(@user.token_bucket.token_count, :>, 0)
end
end
context "#consume!" do
setup do
@user = FactoryBot.create(:user)
TokenBucket.create(user_id: @user.id, last_touched_at: 1.minute.ago, token_count: 1)
end
should "work" do
@user.token_bucket.consume!
assert_operator(@user.token_bucket.token_count, :<, 1)
@user.reload
assert_operator(@user.token_bucket.token_count, :<, 1)
end
end
context "#throttled?" do
setup do
@user = FactoryBot.create(:user)
TokenBucket.create(user_id: @user.id, last_touched_at: 1.minute.ago, token_count: 0)
end
should "work" do
assert(!@user.token_bucket.throttled?)
assert_operator(@user.token_bucket.token_count, :<, 60)
@user.reload
assert_operator(@user.token_bucket.token_count, :<, 60)
end
end
end