docbrown/spec/requests/user_subscriptions_spec.rb
Anna Buianova 7d053471f8
Rubocop fixes in spec/requests (#18946)
* Rubocop fixes in spec/requests

* Fixed spec/requests/api/v0/articles_spec.rb

Co-authored-by: Ridhwana <Ridhwana.Khan16@gmail.com>

Co-authored-by: Ridhwana <Ridhwana.Khan16@gmail.com>
2023-01-12 19:10:16 +03:00

193 lines
9.1 KiB
Ruby

require "rails_helper"
RSpec.describe "UserSubscriptions" do
let(:user) { create(:user) }
before { sign_in user }
describe "GET /user_subscriptions/subscribed - UserSubscriptions#subscribed" do
it "raises an error for missing params" do
expect { get subscribed_user_subscriptions_path, params: {} }.to raise_error(ActionController::ParameterMissing)
end
it "returns true if a user is already subscribed" do
article = create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true)
create(:user_subscription,
subscriber_id: user.id,
subscriber_email: user.email,
author_id: article.user_id,
user_subscription_sourceable: article)
valid_params = { source_type: article.class_name, source_id: article.id }
get subscribed_user_subscriptions_path, params: valid_params
expect(response).to have_http_status(:ok)
expect(response.parsed_body["is_subscribed"]).to be true
end
it "returns false if a user is not already subscribed" do
valid_params = { source_type: "Article", source_id: 999 }
get subscribed_user_subscriptions_path, params: valid_params
expect(response).to have_http_status(:ok)
expect(response.parsed_body["is_subscribed"]).to be false
end
end
describe "POST /user_subscriptions - UserSubscriptions#create" do
it "creates a UserSubscription" do
article = create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true)
valid_attributes = { source_type: article.class_name, source_id: article.id, subscriber_email: user.email }
expect do
post user_subscriptions_path,
headers: { "Content-Type" => "application/json" },
params: { user_subscription: valid_attributes }.to_json
end.to change(UserSubscription, :count).by(1)
user_subscription = UserSubscription.last
expect(user_subscription.subscriber_id).to eq user.id
expect(user_subscription.author_id).to eq article.user_id
expect(user_subscription.user_subscription_sourceable_type).to eq article.class_name
expect(user_subscription.user_subscription_sourceable_id).to eq article.id
end
it "returns an error for an invalid source_type" do
invalid_source_type_attributes = { source_type: "NonExistentSourceType", source_id: "1",
subscriber_email: user.email }
expect do
post user_subscriptions_path,
headers: { "Content-Type" => "application/json" },
params: { user_subscription: invalid_source_type_attributes }.to_json
end.not_to change(UserSubscription, :count)
expect(response).to have_http_status(:unprocessable_entity)
expect(response.parsed_body["error"]).to include("Invalid source_type.")
end
it "returns an error for a source that can't be found" do
invalid_source_attributes = { source_type: "Article", source_id: "99999999" }
expect do
post user_subscriptions_path,
headers: { "Content-Type" => "application/json" },
params: { user_subscription: invalid_source_attributes }.to_json
end.not_to change(UserSubscription, :count)
expect(response).to have_http_status(:unprocessable_entity)
expect(response.parsed_body["error"]).to include("Source not found.")
end
it "returns an error for an inactive source" do
unpublished_article = create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true,
published: false)
invalid_source_attributes = { source_type: unpublished_article.class_name, source_id: unpublished_article.id,
subscriber_email: user.email }
expect do
post user_subscriptions_path,
headers: { "Content-Type" => "application/json" },
params: { user_subscription: invalid_source_attributes }.to_json
end.not_to change(UserSubscription, :count)
expect(response).to have_http_status(:unprocessable_entity)
expect(response.parsed_body["error"]).to include("Source not found. Please make sure your Article is active!")
end
it "returns an error for a source that doesn't have the UserSubscription liquid tag enabled" do
article = create(:article, :with_user_subscription_tag_role_user)
invalid_source_attributes = { source_type: article.class_name, source_id: article.id,
subscriber_email: user.email }
expect do
post user_subscriptions_path,
headers: { "Content-Type" => "application/json" },
params: { user_subscription: invalid_source_attributes }.to_json
end.not_to change(UserSubscription, :count)
expect(response).to have_http_status(:unprocessable_entity)
expect(response.parsed_body["error"]).to include("User subscriptions are not enabled for the source.")
end
it "returns an error for an invalid UserSubscription" do
article = create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true)
# Create the UserSubscription directly so it results in a
# duplicate/invalid record and returns an error. This mimics a user
# trying to subscribe to the same user via the same source, twice.
create(:user_subscription,
subscriber_id: user.id,
subscriber_email: user.email,
author_id: article.user.id,
user_subscription_sourceable: article)
invalid_source_attributes = { source_type: article.class_name, source_id: article.id,
subscriber_email: user.email }
expect do
post user_subscriptions_path,
headers: { "Content-Type" => "application/json" },
params: { user_subscription: invalid_source_attributes }.to_json
end.not_to change(UserSubscription, :count)
expect(response).to have_http_status(:unprocessable_entity)
expect(response.parsed_body["error"]).to include("Subscriber has already been taken")
end
# TODO: [@forem/delightful]: re-enable this once email confirmation is re-enabled
it "returns an error for an email mismatch", pending: "while email confirmation is disabled" do
article = create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true)
invalid_source_attributes = { source_type: article.class_name, source_id: article.id,
subscriber_email: "old_email@test.com" }
expect do
post user_subscriptions_path,
headers: { "Content-Type" => "application/json" },
params: { user_subscription: invalid_source_attributes }.to_json
end.not_to change(UserSubscription, :count)
expect(response).to have_http_status(:unprocessable_entity)
expect(response.parsed_body["error"]).to include("Subscriber email mismatch.")
end
it "returns an error for a subscriber that signed up with Apple" do
allow(user).to receive(:email).and_return("test@privaterelay.appleid.com")
article = create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true)
valid_source_attributes = { source_type: article.class_name, source_id: article.id, subscriber_email: user.email }
expect do
post user_subscriptions_path,
headers: { "Content-Type" => "application/json" },
params: { user_subscription: valid_source_attributes }.to_json
end.not_to change(UserSubscription, :count)
expect(response).to have_http_status(:unprocessable_entity)
error_message = "Subscriber email Can't subscribe with an Apple private relay. Please update email."
expect(response.parsed_body["error"]).to include(error_message)
end
end
context "when rate limiting" do
let(:rate_limiter) { RateLimitChecker.new(user) }
let(:article) { create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true) }
let(:valid_attributes) { { source_type: article.class_name, source_id: article.id, subscriber_email: user.email } }
before { allow(RateLimitChecker).to receive(:new).and_return(rate_limiter) }
it "increments rate limit for user_subscription_creation" do
allow(rate_limiter).to receive(:track_limit_by_action)
post user_subscriptions_path,
headers: { "Content-Type" => "application/json" },
params: { user_subscription: valid_attributes }.to_json
expect(rate_limiter).to have_received(:track_limit_by_action).with(:user_subscription_creation)
end
it "returns a 429 status when rate limit is reached" do
allow(rate_limiter).to receive(:limit_by_action).and_return(true)
post user_subscriptions_path,
headers: { "Content-Type" => "application/json" },
params: { user_subscription: valid_attributes }.to_json
expect(response).to have_http_status(:too_many_requests)
expected_retry_after = RateLimitChecker::ACTION_LIMITERS.dig(:user_subscription_creation, :retry_after)
expect(response.headers["Retry-After"]).to eq(expected_retry_after)
end
end
end