discourse/spec/requests/bookmarks_controller_spec.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

240 lines
7.9 KiB
Ruby
Raw Normal View History

Improving bookmarks part 1 (#8466) Note: All of this functionality is hidden behind a hidden, default false, site setting called `enable_bookmarks_with_reminders`. Also, any feedback on Ember code would be greatly appreciated! This is part 1 of the bookmark improvements. The next PR will address the backend logic to send reminder notifications for bookmarked posts to users. This PR adds the following functionality: * We are adding a new `bookmarks` table and `Bookmark` model to make the bookmarks a first-class citizen and to allow attaching reminders to them. * Posts now have a new button in their actions menu that has the icon of an actual book * Clicking the button opens the new bookmark modal. * Both name and the reminder type are optional. * If you close the modal without doing anything, the bookmark is saved with no reminder. * If you click the Cancel button, no bookmark is saved at all. * All of the reminder type tiles are dynamic and the times they show will be based on your user timezone set in your profile (this should already be set for you). * If for some reason a user does not have their timezone set they will not be able to set a reminder, but they will still be able to create a bookmark. * A bookmark can be deleted by clicking on the book icon again which will be red if the post is bookmarked. This PR does NOT do anything to migrate or change existing bookmarks in the form of `PostActions`, the two features live side-by-side here. Also this does nothing to the topic bookmarking.
2019-12-11 12:04:02 +08:00
# frozen_string_literal: true
RSpec.describe BookmarksController do
Improving bookmarks part 1 (#8466) Note: All of this functionality is hidden behind a hidden, default false, site setting called `enable_bookmarks_with_reminders`. Also, any feedback on Ember code would be greatly appreciated! This is part 1 of the bookmark improvements. The next PR will address the backend logic to send reminder notifications for bookmarked posts to users. This PR adds the following functionality: * We are adding a new `bookmarks` table and `Bookmark` model to make the bookmarks a first-class citizen and to allow attaching reminders to them. * Posts now have a new button in their actions menu that has the icon of an actual book * Clicking the button opens the new bookmark modal. * Both name and the reminder type are optional. * If you close the modal without doing anything, the bookmark is saved with no reminder. * If you click the Cancel button, no bookmark is saved at all. * All of the reminder type tiles are dynamic and the times they show will be based on your user timezone set in your profile (this should already be set for you). * If for some reason a user does not have their timezone set they will not be able to set a reminder, but they will still be able to create a bookmark. * A bookmark can be deleted by clicking on the book icon again which will be red if the post is bookmarked. This PR does NOT do anything to migrate or change existing bookmarks in the form of `PostActions`, the two features live side-by-side here. Also this does nothing to the topic bookmarking.
2019-12-11 12:04:02 +08:00
let(:current_user) { Fabricate(:user) }
let(:user_2) { Fabricate(:user) }
Improving bookmarks part 1 (#8466) Note: All of this functionality is hidden behind a hidden, default false, site setting called `enable_bookmarks_with_reminders`. Also, any feedback on Ember code would be greatly appreciated! This is part 1 of the bookmark improvements. The next PR will address the backend logic to send reminder notifications for bookmarked posts to users. This PR adds the following functionality: * We are adding a new `bookmarks` table and `Bookmark` model to make the bookmarks a first-class citizen and to allow attaching reminders to them. * Posts now have a new button in their actions menu that has the icon of an actual book * Clicking the button opens the new bookmark modal. * Both name and the reminder type are optional. * If you close the modal without doing anything, the bookmark is saved with no reminder. * If you click the Cancel button, no bookmark is saved at all. * All of the reminder type tiles are dynamic and the times they show will be based on your user timezone set in your profile (this should already be set for you). * If for some reason a user does not have their timezone set they will not be able to set a reminder, but they will still be able to create a bookmark. * A bookmark can be deleted by clicking on the book icon again which will be red if the post is bookmarked. This PR does NOT do anything to migrate or change existing bookmarks in the form of `PostActions`, the two features live side-by-side here. Also this does nothing to the topic bookmarking.
2019-12-11 12:04:02 +08:00
let(:bookmark_post) { Fabricate(:post) }
let(:bookmark_post_2) { Fabricate(:post) }
let(:bookmark_topic) { Fabricate(:topic) }
let(:bookmark_user) { current_user }
Improving bookmarks part 1 (#8466) Note: All of this functionality is hidden behind a hidden, default false, site setting called `enable_bookmarks_with_reminders`. Also, any feedback on Ember code would be greatly appreciated! This is part 1 of the bookmark improvements. The next PR will address the backend logic to send reminder notifications for bookmarked posts to users. This PR adds the following functionality: * We are adding a new `bookmarks` table and `Bookmark` model to make the bookmarks a first-class citizen and to allow attaching reminders to them. * Posts now have a new button in their actions menu that has the icon of an actual book * Clicking the button opens the new bookmark modal. * Both name and the reminder type are optional. * If you close the modal without doing anything, the bookmark is saved with no reminder. * If you click the Cancel button, no bookmark is saved at all. * All of the reminder type tiles are dynamic and the times they show will be based on your user timezone set in your profile (this should already be set for you). * If for some reason a user does not have their timezone set they will not be able to set a reminder, but they will still be able to create a bookmark. * A bookmark can be deleted by clicking on the book icon again which will be red if the post is bookmarked. This PR does NOT do anything to migrate or change existing bookmarks in the form of `PostActions`, the two features live side-by-side here. Also this does nothing to the topic bookmarking.
2019-12-11 12:04:02 +08:00
describe "#create" do
before { sign_in(current_user) }
it "rate limits creates" do
SiteSetting.max_bookmarks_per_day = 1
RateLimiter.enable
post "/bookmarks.json",
params: {
bookmarkable_id: bookmark_post.id,
bookmarkable_type: "Post",
reminder_at: (Time.zone.now + 1.day).iso8601,
}
expect(response.status).to eq(200)
post "/bookmarks.json",
params: {
bookmarkable_id: bookmark_post.id,
bookmarkable_type: "Post",
}
expect(response.status).to eq(429)
end
context "if the user reached the max bookmark limit" do
before { SiteSetting.max_bookmarks_per_user = 1 }
it "returns failed JSON with a 400 error" do
post "/bookmarks.json",
params: {
bookmarkable_id: bookmark_post.id,
bookmarkable_type: "Post",
reminder_at: (Time.zone.now + 1.day).iso8601,
}
post "/bookmarks.json",
params: {
bookmarkable_id: bookmark_post.id,
bookmarkable_type: "Post",
}
expect(response.status).to eq(400)
user_bookmarks_url = "#{Discourse.base_url}/my/activity/bookmarks"
expect(response.parsed_body["errors"]).to include(
I18n.t(
"bookmarks.errors.too_many",
user_bookmarks_url: user_bookmarks_url,
limit: SiteSetting.max_bookmarks_per_user,
),
)
end
end
context "if the user already has bookmarked the record" do
before do
Fabricate(:bookmark, bookmarkable: bookmark_post, user: bookmark_user)
Fabricate(:bookmark, bookmarkable: bookmark_topic, user: bookmark_user)
end
it "returns failed JSON with a 400 error" do
post "/bookmarks.json",
params: {
bookmarkable_id: bookmark_post.id,
bookmarkable_type: "Post",
reminder_at: (Time.zone.now + 1.day).iso8601,
}
expect(response.status).to eq(400)
expect(response.parsed_body["errors"]).to include(
I18n.t("bookmarks.errors.already_bookmarked", type: "Post"),
)
post "/bookmarks.json",
params: {
bookmarkable_id: bookmark_topic.id,
bookmarkable_type: "Topic",
reminder_at: (Time.zone.now + 1.day).iso8601,
}
expect(response.status).to eq(400)
expect(response.parsed_body["errors"]).to include(
I18n.t("bookmarks.errors.already_bookmarked", type: "Topic"),
)
end
end
Improving bookmarks part 1 (#8466) Note: All of this functionality is hidden behind a hidden, default false, site setting called `enable_bookmarks_with_reminders`. Also, any feedback on Ember code would be greatly appreciated! This is part 1 of the bookmark improvements. The next PR will address the backend logic to send reminder notifications for bookmarked posts to users. This PR adds the following functionality: * We are adding a new `bookmarks` table and `Bookmark` model to make the bookmarks a first-class citizen and to allow attaching reminders to them. * Posts now have a new button in their actions menu that has the icon of an actual book * Clicking the button opens the new bookmark modal. * Both name and the reminder type are optional. * If you close the modal without doing anything, the bookmark is saved with no reminder. * If you click the Cancel button, no bookmark is saved at all. * All of the reminder type tiles are dynamic and the times they show will be based on your user timezone set in your profile (this should already be set for you). * If for some reason a user does not have their timezone set they will not be able to set a reminder, but they will still be able to create a bookmark. * A bookmark can be deleted by clicking on the book icon again which will be red if the post is bookmarked. This PR does NOT do anything to migrate or change existing bookmarks in the form of `PostActions`, the two features live side-by-side here. Also this does nothing to the topic bookmarking.
2019-12-11 12:04:02 +08:00
end
describe "#destroy" do
before { sign_in(current_user) }
let!(:bookmark) { Fabricate(:bookmark, bookmarkable: bookmark_post, user: bookmark_user) }
it "destroys the bookmark" do
delete "/bookmarks/#{bookmark.id}.json"
expect(Bookmark.find_by(id: bookmark.id)).to eq(nil)
end
it "returns an indication of whether there are still bookmarks in the topic" do
delete "/bookmarks/#{bookmark.id}.json"
expect(Bookmark.find_by(id: bookmark.id)).to eq(nil)
expect(response.parsed_body["topic_bookmarked"]).to eq(false)
bm2 =
Fabricate(
:bookmark,
user: bookmark_user,
bookmarkable: Fabricate(:post, topic: bookmark_post.topic),
)
bm3 = Fabricate(:bookmark, user: bookmark_user, bookmarkable: bookmark_post.topic)
delete "/bookmarks/#{bm2.id}.json"
expect(Bookmark.find_by(id: bm2.id)).to eq(nil)
expect(response.parsed_body["topic_bookmarked"]).to eq(true)
delete "/bookmarks/#{bm3.id}.json"
expect(Bookmark.find_by(id: bm3.id)).to eq(nil)
expect(response.parsed_body["topic_bookmarked"]).to eq(false)
end
context "if the bookmark has already been destroyed" do
it "returns failed JSON with a 403 error" do
bookmark.destroy!
delete "/bookmarks/#{bookmark.id}.json"
expect(response.status).to eq(404)
expect(response.parsed_body["errors"].first).to include(I18n.t("not_found"))
end
end
context "if the bookmark does not belong to the user" do
let(:bookmark_user) { Fabricate(:user) }
it "returns failed JSON with a 403 error" do
delete "/bookmarks/#{bookmark.id}.json"
expect(response.status).to eq(403)
expect(response.parsed_body["errors"].first).to include(I18n.t("invalid_access"))
end
end
end
describe "#bulk" do
it "needs you to be logged in" do
put "/bookmarks/bulk.json"
expect(response.status).to eq(403)
end
describe "when logged in" do
before { sign_in(bookmark_user) }
let!(:bookmark) { Fabricate(:bookmark, bookmarkable: bookmark_post, user: bookmark_user) }
let!(:bookmark_2) { Fabricate(:bookmark, bookmarkable: bookmark_post_2, user: bookmark_user) }
let!(:operation) { { type: "clear_reminder" } }
let!(:bookmark_ids) { [bookmark.id, bookmark_2.id] }
it "requires a list of bookmark_ids" do
put "/bookmarks/bulk.json", params: { operation: operation }
expect(response.status).to eq(400)
end
it "requires an operation param" do
put "/bookmarks/bulk.json", params: { bookmark_ids: bookmark_ids }
expect(response.status).to eq(400)
end
it "can clear reminder for the given bookmarks" do
expect do
put "/bookmarks/bulk.json",
params: {
operation: {
type: "clear_reminder",
},
bookmark_ids: [bookmark.id],
}
expect(response.status).to eq(200)
end.to change { Bookmark.find(bookmark.id).reminder_set_at }.to(nil)
end
it "can delete bookmarks" do
expect do
put "/bookmarks/bulk.json",
params: {
operation: {
type: "delete",
},
bookmark_ids: [bookmark.id, bookmark_2.id],
}
expect(response.status).to eq(200)
end.to change { Bookmark.where(id: [bookmark, bookmark_2]).count }.from(2).to(0)
end
end
describe "can't update other user's bookmarks" do
before { sign_in(user_2) }
let!(:bookmark) { Fabricate(:bookmark, bookmarkable: bookmark_post, user: bookmark_user) }
let!(:bookmark_2) { Fabricate(:bookmark, bookmarkable: bookmark_post_2, user: bookmark_user) }
let!(:operation) { { type: "clear_reminder" } }
let!(:bookmark_ids) { [bookmark.id, bookmark_2.id] }
it "CAN'T clear reminder if the bookmark does not belong to the user" do
expect do
put "/bookmarks/bulk.json",
params: {
operation: {
type: "clear_reminder",
},
bookmark_ids: [bookmark.id, bookmark_2.id],
}
expect(response.status).to eq(403)
expect(response.parsed_body["errors"].first).to include(I18n.t("invalid_access"))
end.to_not change { Bookmark.find(bookmark.id).reminder_set_at }
end
it "CAN'T delete bookmarks that does not belong to the user" do
expect do
put "/bookmarks/bulk.json",
params: {
operation: {
type: "delete",
},
bookmark_ids: [bookmark.id, bookmark_2.id],
}
expect(response.status).to eq(403)
expect(response.parsed_body["errors"].first).to include(I18n.t("invalid_access"))
end.to_not change { Bookmark.where(id: [bookmark, bookmark_2]).count }.from(2)
end
end
end
Improving bookmarks part 1 (#8466) Note: All of this functionality is hidden behind a hidden, default false, site setting called `enable_bookmarks_with_reminders`. Also, any feedback on Ember code would be greatly appreciated! This is part 1 of the bookmark improvements. The next PR will address the backend logic to send reminder notifications for bookmarked posts to users. This PR adds the following functionality: * We are adding a new `bookmarks` table and `Bookmark` model to make the bookmarks a first-class citizen and to allow attaching reminders to them. * Posts now have a new button in their actions menu that has the icon of an actual book * Clicking the button opens the new bookmark modal. * Both name and the reminder type are optional. * If you close the modal without doing anything, the bookmark is saved with no reminder. * If you click the Cancel button, no bookmark is saved at all. * All of the reminder type tiles are dynamic and the times they show will be based on your user timezone set in your profile (this should already be set for you). * If for some reason a user does not have their timezone set they will not be able to set a reminder, but they will still be able to create a bookmark. * A bookmark can be deleted by clicking on the book icon again which will be red if the post is bookmarked. This PR does NOT do anything to migrate or change existing bookmarks in the form of `PostActions`, the two features live side-by-side here. Also this does nothing to the topic bookmarking.
2019-12-11 12:04:02 +08:00
end