mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-10-23 22:26:48 +09:00
Hello world
First open source release of Campfire 🎉
This commit is contained in:
commit
df76a227dc
664 files changed
+36235
No files matched your search
Whitespace-only changes.
@@ -0,0 +1,14 @@
|
||||
require "test_helper"
|
||||
|
||||
class Accounts::Bots::KeysControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "update" do
|
||||
assert_changes -> { users(:bender).reload.bot_token } do
|
||||
put account_bot_key_url(users(:bender))
|
||||
assert_redirected_to account_bots_url
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,45 @@
|
||||
require "test_helper"
|
||||
|
||||
class Accounts::BotsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "index" do
|
||||
get account_bots_url
|
||||
assert_response :ok
|
||||
end
|
||||
|
||||
test "create" do
|
||||
get new_account_bot_url
|
||||
assert_response :ok
|
||||
|
||||
post account_bots_url, params: { user: { name: "Bender's Friend" } }
|
||||
assert_redirected_to account_bots_url
|
||||
assert_equal "Bender's Friend", User.bot.last.name
|
||||
end
|
||||
|
||||
test "update" do
|
||||
get edit_account_bot_url(users(:bender))
|
||||
assert_response :ok
|
||||
|
||||
put account_bot_url(users(:bender)), params: { user: { name: "Bender's New Friend" } }
|
||||
assert_redirected_to account_bots_url
|
||||
assert_equal "Bender's New Friend", users(:bender).reload.name
|
||||
end
|
||||
|
||||
test "destroy" do
|
||||
assert_difference -> { User.active_bots.count }, -1 do
|
||||
delete account_bot_url(users(:bender))
|
||||
end
|
||||
|
||||
assert users(:bender).reload.deactivated?
|
||||
end
|
||||
|
||||
test "remove webhook" do
|
||||
assert_difference -> { Webhook.count }, -1 do
|
||||
put account_bot_url(users(:bender)), params: { user: { name: "Bender's New Friend", webook_url: "" } }
|
||||
assert_redirected_to account_bots_url
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,29 @@
|
||||
require "test_helper"
|
||||
|
||||
class Accounts::CustomStylesControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "edit" do
|
||||
get edit_account_custom_styles_url
|
||||
assert_response :ok
|
||||
end
|
||||
|
||||
test "update" do
|
||||
assert users(:david).administrator?
|
||||
|
||||
put account_custom_styles_url, params: { account: { custom_styles: ":root { --color-text: red; }" } }
|
||||
|
||||
assert_redirected_to edit_account_custom_styles_url
|
||||
assert_equal accounts(:signal).custom_styles, ":root { --color-text: red; }"
|
||||
end
|
||||
|
||||
test "non-admins cannot update" do
|
||||
sign_in :kevin
|
||||
assert users(:kevin).member?
|
||||
|
||||
put account_custom_styles_url, params: { account: { custom_styles: ":root { --color-text: red; }" } }
|
||||
assert_response :forbidden
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,20 @@
|
||||
require "test_helper"
|
||||
|
||||
class Accounts::JoinCodesControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "create new join code" do
|
||||
assert_changes -> { accounts(:signal).reload.join_code } do
|
||||
post account_join_code_url
|
||||
assert_redirected_to edit_account_url
|
||||
end
|
||||
end
|
||||
|
||||
test "only administrators can create new join codes" do
|
||||
sign_in :jz
|
||||
post account_join_code_url
|
||||
assert_response :forbidden
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
require "test_helper"
|
||||
require "vips"
|
||||
|
||||
class Accounts::LogosControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "show stock" do
|
||||
get account_logo_url
|
||||
assert_valid_png_response size: 512
|
||||
end
|
||||
|
||||
test "show stock small size" do
|
||||
get account_logo_url(size: :small)
|
||||
assert_valid_png_response size: 192
|
||||
end
|
||||
|
||||
test "show custom" do
|
||||
accounts(:signal).update! logo: fixture_file_upload("moon.jpg", "image/jpeg")
|
||||
|
||||
get account_logo_url
|
||||
assert_valid_png_response size: 512
|
||||
end
|
||||
|
||||
test "show custom small size" do
|
||||
accounts(:signal).update! logo: fixture_file_upload("moon.jpg", "image/jpeg")
|
||||
|
||||
get account_logo_url(size: :small)
|
||||
assert_valid_png_response size: 192
|
||||
end
|
||||
|
||||
test "destroy" do
|
||||
accounts(:signal).update! logo: fixture_file_upload("moon.jpg", "image/jpeg")
|
||||
|
||||
delete account_logo_url
|
||||
assert_redirected_to edit_account_url
|
||||
assert_not accounts(:signal).reload.logo.attached?
|
||||
end
|
||||
|
||||
private
|
||||
def assert_valid_png_response(size:)
|
||||
assert_equal @response.headers["content-type"], "image/png"
|
||||
|
||||
image = ::Vips::Image.new_from_buffer(@response.body, "")
|
||||
assert_equal size, image.width
|
||||
assert_equal size, image.height
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,35 @@
|
||||
require "test_helper"
|
||||
|
||||
class Accounts::UsersControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "update" do
|
||||
assert users(:david).administrator?
|
||||
|
||||
put account_user_url(users(:david)), params: { user: { role: "administrator" } }
|
||||
|
||||
assert_redirected_to edit_account_url
|
||||
assert users(:david).reload.administrator?
|
||||
end
|
||||
|
||||
test "destroy" do
|
||||
assert_difference -> { User.active.count }, -1 do
|
||||
delete account_user_url(users(:david))
|
||||
end
|
||||
|
||||
assert_redirected_to edit_account_url
|
||||
assert_nil User.active.find_by(id: users(:david).id)
|
||||
end
|
||||
|
||||
test "non-admins cannot perform actions" do
|
||||
sign_in :kevin
|
||||
|
||||
put account_user_url(users(:david)), params: { user: { role: "administrator" } }
|
||||
assert_response :forbidden
|
||||
|
||||
delete account_user_url(users(:david))
|
||||
assert_response :forbidden
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,29 @@
|
||||
require "test_helper"
|
||||
|
||||
class AccountsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "edit" do
|
||||
get edit_account_url
|
||||
assert_response :ok
|
||||
end
|
||||
|
||||
test "update" do
|
||||
assert users(:david).administrator?
|
||||
|
||||
put account_url, params: { account: { name: "Different" } }
|
||||
|
||||
assert_redirected_to edit_account_url
|
||||
assert_equal accounts(:signal).name, "Different"
|
||||
end
|
||||
|
||||
test "non-admins cannot update" do
|
||||
sign_in :kevin
|
||||
assert users(:kevin).member?
|
||||
|
||||
put account_url, params: { account: { name: "Different" } }
|
||||
assert_response :forbidden
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
require "test_helper"
|
||||
|
||||
class Autocompletable::UsersControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "search returns matching users" do
|
||||
get autocompletable_users_url(format: :json), params: { query: "da" }
|
||||
|
||||
assert_response :success
|
||||
assert_equal "David", response.parsed_body.first["name"]
|
||||
end
|
||||
|
||||
test "search results escape HTML in names" do
|
||||
users(:david).update!(name: "David <script>alert(123)</script>")
|
||||
|
||||
get autocompletable_users_url(format: :json), params: { query: "da" }
|
||||
|
||||
assert_response :success
|
||||
assert_equal "David <script>alert(123)</script>", response.parsed_body.first["name"]
|
||||
end
|
||||
|
||||
test "room search returns matching users" do
|
||||
get autocompletable_users_url(room_id: rooms(:hq).id, format: :json), params: { query: "da" }
|
||||
|
||||
assert_response :success
|
||||
assert_equal "David", response.parsed_body.first["name"]
|
||||
end
|
||||
|
||||
test "room search is scoped by membership" do
|
||||
sign_in :kevin
|
||||
|
||||
assert_not_includes users(:kevin).rooms, rooms(:watercooler)
|
||||
|
||||
assert_raises ActiveRecord::RecordNotFound do
|
||||
get autocompletable_users_url(room_id: rooms(:watercooler).id, format: :json), params: { query: "da" }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
require "test_helper"
|
||||
|
||||
class FirstRunsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
Account.destroy_all
|
||||
User.destroy_all
|
||||
Room.destroy_all
|
||||
end
|
||||
|
||||
test "new is permitted when no other users exit" do
|
||||
get first_run_url
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "new is not permitted when account exist" do
|
||||
Account.create!(name: "Chat")
|
||||
|
||||
get first_run_url
|
||||
assert_redirected_to root_url
|
||||
end
|
||||
|
||||
test "create" do
|
||||
assert_difference -> { Room.count }, 1 do
|
||||
assert_difference -> { User.count }, 1 do
|
||||
post first_run_url, params: { account: { name: "37signals" }, user: { name: "New Person", email_address: "new@37signals.com", password: "secret123456" } }
|
||||
end
|
||||
end
|
||||
|
||||
assert_redirected_to root_url
|
||||
|
||||
assert parsed_cookies.signed[:session_token]
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
require "test_helper"
|
||||
|
||||
class Messages::BoostsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
@message = messages(:first)
|
||||
end
|
||||
|
||||
test "create" do
|
||||
assert_turbo_stream_broadcasts [ @message.room, :messages ], count: 1 do
|
||||
assert_difference -> { @message.boosts.count }, 1 do
|
||||
post message_boosts_url(@message, format: :turbo_stream), params: { boost: { content: "Morning!" } }
|
||||
assert_redirected_to message_boosts_url(@message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "destroy" do
|
||||
assert_turbo_stream_broadcasts [ @message.room, :messages ], count: 1 do
|
||||
assert_difference -> { @message.boosts.count }, -1 do
|
||||
delete message_boost_url(@message, boosts(:first), format: :turbo_stream)
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,47 @@
|
||||
require "test_helper"
|
||||
|
||||
class Messages::ByBotsControlleTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
@room = rooms(:watercooler)
|
||||
end
|
||||
|
||||
test "create" do
|
||||
assert_difference -> { Message.count }, +1 do
|
||||
post room_bot_messages_url(@room, users(:bender).bot_key), params: "Hello Bot World!"
|
||||
assert_equal "Hello Bot World!", Message.last.plain_text_body
|
||||
end
|
||||
end
|
||||
|
||||
test "create with UTF-8 content" do
|
||||
assert_difference -> { Message.count }, +1 do
|
||||
post room_bot_messages_url(@room, users(:bender).bot_key), params: "Hello 👋!"
|
||||
assert_equal "Hello 👋!", Message.last.plain_text_body
|
||||
end
|
||||
end
|
||||
|
||||
test "create file" do
|
||||
assert_difference -> { Message.count }, +1 do
|
||||
post room_bot_messages_url(@room, users(:bender).bot_key), params: { attachment: fixture_file_upload("moon.jpg", "image/jpeg") }
|
||||
assert Message.last.attachment.present?
|
||||
end
|
||||
end
|
||||
|
||||
test "create does not trigger a webhook to the sending bot if it mentions itself" do
|
||||
body = "<div>Hey #{mention_attachment_for(:bender)}</div>"
|
||||
|
||||
assert_no_enqueued_jobs only: Bot::WebhookJob do
|
||||
post room_bot_messages_url(@room, users(:bender).bot_key), params: body
|
||||
end
|
||||
end
|
||||
|
||||
test "create does not trigger a webhook to the sending bot in a direct room" do
|
||||
assert_no_enqueued_jobs only: Bot::WebhookJob do
|
||||
post room_bot_messages_url(rooms(:bender_and_kevin), users(:bender).bot_key), params: "Talking to myself again!"
|
||||
end
|
||||
end
|
||||
|
||||
test "denied index" do
|
||||
get room_messages_url(@room, bot_key: users(:bender).bot_key, format: :json)
|
||||
assert_response :forbidden
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,152 @@
|
||||
require "test_helper"
|
||||
|
||||
class MessagesControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
host! "once.campfire.test"
|
||||
|
||||
sign_in :david
|
||||
@room = rooms(:watercooler)
|
||||
@messages = @room.messages.ordered.to_a
|
||||
end
|
||||
|
||||
test "index returns the last page by default" do
|
||||
get room_messages_url(@room)
|
||||
|
||||
assert_response :success
|
||||
ensure_messages_present @messages.last
|
||||
end
|
||||
|
||||
test "index returns a page before the specified message" do
|
||||
get room_messages_url(@room, before: @messages.third)
|
||||
|
||||
assert_response :success
|
||||
ensure_messages_present @messages.first, @messages.second
|
||||
ensure_messages_not_present @messages.third, @messages.fourth, @messages.fifth
|
||||
end
|
||||
|
||||
test "index returns a page after the specified message" do
|
||||
get room_messages_url(@room, after: @messages.third)
|
||||
|
||||
assert_response :success
|
||||
ensure_messages_present @messages.fourth, @messages.fifth
|
||||
ensure_messages_not_present @messages.first, @messages.second, @messages.third
|
||||
end
|
||||
|
||||
test "index returns no_content when there are no messages" do
|
||||
@room.messages.destroy_all
|
||||
|
||||
get room_messages_url(@room)
|
||||
|
||||
assert_response :no_content
|
||||
end
|
||||
|
||||
test "get renders a single message belonging to the user" do
|
||||
message = @room.messages.where(creator: users(:david)).first
|
||||
|
||||
get room_message_url(@room, message)
|
||||
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "creating a message broadcasts the message to the room" do
|
||||
post room_messages_url(@room, format: :turbo_stream), params: { message: { body: "New one", client_message_id: 999 } }
|
||||
|
||||
assert_rendered_turbo_stream_broadcast @room, :messages, action: "append", target: [ @room, :messages ] do
|
||||
assert_select ".message__body", text: /New one/
|
||||
assert_copy_link_button room_at_message_url(@room, Message.last, host: "once.campfire.test")
|
||||
end
|
||||
end
|
||||
|
||||
test "creating a message broadcasts unread room" do
|
||||
assert_broadcasts "unread_rooms", 1 do
|
||||
post room_messages_url(@room, format: :turbo_stream), params: { message: { body: "New one", client_message_id: 999 } }
|
||||
end
|
||||
end
|
||||
|
||||
test "update updates a message belonging to the user" do
|
||||
message = @room.messages.where(creator: users(:david)).first
|
||||
|
||||
Turbo::StreamsChannel.expects(:broadcast_replace_to).once
|
||||
put room_message_url(@room, message), params: { message: { body: "Updated body" } }
|
||||
|
||||
assert_redirected_to room_message_url(@room, message)
|
||||
assert_equal "Updated body", message.reload.plain_text_body
|
||||
end
|
||||
|
||||
test "admin updates a message belonging to another user" do
|
||||
message = @room.messages.where(creator: users(:jason)).first
|
||||
|
||||
Turbo::StreamsChannel.expects(:broadcast_replace_to).once
|
||||
put room_message_url(@room, message), params: { message: { body: "Updated body" } }
|
||||
|
||||
assert_redirected_to room_message_url(@room, message)
|
||||
assert_equal "Updated body", message.reload.plain_text_body
|
||||
end
|
||||
|
||||
test "destroy destroys a message belonging to the user" do
|
||||
message = @room.messages.where(creator: users(:david)).first
|
||||
|
||||
assert_difference -> { Message.count }, -1 do
|
||||
Turbo::StreamsChannel.expects(:broadcast_remove_to).once
|
||||
delete room_message_url(@room, message, format: :turbo_stream)
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
|
||||
test "admin destroy destroys a message belonging to another user" do
|
||||
assert users(:david).administrator?
|
||||
message = @room.messages.where(creator: users(:jason)).first
|
||||
|
||||
assert_difference -> { Message.count }, -1 do
|
||||
Turbo::StreamsChannel.expects(:broadcast_remove_to).once
|
||||
delete room_message_url(@room, message, format: :turbo_stream)
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
|
||||
test "ensure non-admin can't update a message belonging to another user" do
|
||||
sign_in :jz
|
||||
assert_not users(:jz).administrator?
|
||||
|
||||
room = rooms(:designers)
|
||||
message = room.messages.where(creator: users(:jason)).first
|
||||
|
||||
put room_message_url(room, message), params: { message: { body: "Updated body" } }
|
||||
assert_response :forbidden
|
||||
end
|
||||
|
||||
test "ensure non-admin can't destroy a message belonging to another user" do
|
||||
sign_in :jz
|
||||
assert_not users(:jz).administrator?
|
||||
|
||||
room = rooms(:designers)
|
||||
message = room.messages.where(creator: users(:jason)).first
|
||||
|
||||
delete room_message_url(room, message, format: :turbo_stream)
|
||||
assert_response :forbidden
|
||||
end
|
||||
|
||||
test "mentioning a bot triggers a webhook" do
|
||||
WebMock.stub_request(:post, webhooks(:bender).url).to_return(status: 200)
|
||||
|
||||
assert_enqueued_jobs 1, only: Bot::WebhookJob do
|
||||
post room_messages_url(@room, format: :turbo_stream), params: { message: {
|
||||
body: "<div>Hey #{mention_attachment_for(:bender)}</div>", client_message_id: 999 } }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def ensure_messages_present(*messages, count: 1)
|
||||
messages.each do |message|
|
||||
assert_select "#" + dom_id(message), count:
|
||||
end
|
||||
end
|
||||
|
||||
def ensure_messages_not_present(*messages)
|
||||
ensure_messages_present *messages, count: 0
|
||||
end
|
||||
|
||||
def assert_copy_link_button(url)
|
||||
assert_select ".btn[title='Copy link'][data-copy-to-clipboard-content-value='#{url}']"
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,15 @@
|
||||
require "test_helper"
|
||||
|
||||
class QrCodeControllerTest < ActionDispatch::IntegrationTest
|
||||
test "show renders a QR code as a cacheable SVG image" do
|
||||
id = Base64.urlsafe_encode64("http://example.com")
|
||||
|
||||
get qr_code_path(id)
|
||||
|
||||
assert_response :success
|
||||
assert_includes response.content_type, "image/svg+xml"
|
||||
|
||||
assert_equal 1.year, response.cache_control[:max_age].to_i
|
||||
assert response.cache_control[:public]
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,68 @@
|
||||
require "test_helper"
|
||||
|
||||
class Rooms::ClosedsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "show redirects to get general show" do
|
||||
get rooms_open_url(users(:david).rooms.closeds.last)
|
||||
assert_redirected_to room_url(users(:david).rooms.closeds.last)
|
||||
end
|
||||
|
||||
test "new" do
|
||||
get new_rooms_closed_url
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "create" do
|
||||
assert_turbo_stream_broadcasts [ users(:david), :rooms ], count: 1 do
|
||||
assert_turbo_stream_broadcasts [ users(:kevin), :rooms ], count: 1 do
|
||||
assert_turbo_stream_broadcasts [ users(:jason), :rooms ], count: 1 do
|
||||
post rooms_closeds_url, params: { room: { name: "My New Room" }, user_ids: [ users(:david).id, users(:kevin).id, users(:jason).id ] }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
new_room = Room.last
|
||||
assert_equal new_room.memberships.count, 3
|
||||
assert_redirected_to room_url(Room.last)
|
||||
end
|
||||
|
||||
test "update with membership revisions" do
|
||||
assert_difference -> { rooms(:designers).reload.users.count }, -1 do
|
||||
put rooms_closed_url(rooms(:designers)), params: {
|
||||
room: { name: "New Name" }, user_ids: rooms(:designers).users.without(users(:jason)).collect(&:id)
|
||||
}
|
||||
end
|
||||
|
||||
assert_redirected_to room_url(rooms(:designers))
|
||||
assert rooms(:designers).reload.name, "New Name"
|
||||
end
|
||||
|
||||
test "update an open room to be closed" do
|
||||
put rooms_closed_url(rooms(:pets)), params: { room: { name: "Doesn't matter" }, user_ids: [ users(:david).id, users(:jason).id ] }
|
||||
assert_equal rooms(:pets).memberships.count, 2
|
||||
end
|
||||
|
||||
test "only admins or creators can update" do
|
||||
sign_in :jz
|
||||
|
||||
assert_turbo_stream_broadcasts :rooms, count: 0 do
|
||||
put rooms_closed_url(rooms(:designers)), params: { room: { name: "New Name" } }
|
||||
end
|
||||
|
||||
assert_response :forbidden
|
||||
assert rooms(:designers).reload.name, "Designers"
|
||||
end
|
||||
|
||||
test "remove yourself" do
|
||||
assert_difference -> { users(:david).rooms.count }, -1 do
|
||||
put rooms_closed_url(rooms(:designers), params: { room: { name: "Designers" }, user_ids: [ users(:jason).id, users(:jz).id ] })
|
||||
|
||||
assert_redirected_to room_url(rooms(:designers))
|
||||
follow_redirect!
|
||||
assert_redirected_to root_url
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
require "test_helper"
|
||||
|
||||
class Rooms::DirectsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "create" do
|
||||
post rooms_directs_url, params: { user_ids: [ users(:jz).id ] }
|
||||
|
||||
room = Room.last
|
||||
assert_redirected_to room_url(room)
|
||||
assert room.users.include?(users(:david))
|
||||
assert room.users.include?(users(:jz))
|
||||
end
|
||||
|
||||
test "create only once per user set" do
|
||||
assert_difference -> { Room.all.count }, +1 do
|
||||
post rooms_directs_url, params: { user_ids: [ users(:jz).id ] }
|
||||
post rooms_directs_url, params: { user_ids: [ users(:jz).id ] }
|
||||
end
|
||||
end
|
||||
|
||||
test "destroy only allowed for all room users" do
|
||||
sign_in :kevin
|
||||
|
||||
assert_difference -> { Room.count }, -1 do
|
||||
delete rooms_direct_url(rooms(:david_and_kevin))
|
||||
assert_redirected_to root_url
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,46 @@
|
||||
require "test_helper"
|
||||
|
||||
class Rooms::InvolvementsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "show" do
|
||||
get room_involvement_url(rooms(:designers))
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "update involvement sends turbo update when becoming visible and when going invisible" do
|
||||
assert_turbo_stream_broadcasts [ users(:david), :rooms ], count: 1 do
|
||||
assert_changes -> { memberships(:david_watercooler).reload.involvement }, from: "everything", to: "invisible" do
|
||||
put room_involvement_url(rooms(:watercooler)), params: { involvement: "invisible" }
|
||||
assert_redirected_to room_involvement_url(rooms(:watercooler))
|
||||
end
|
||||
end
|
||||
|
||||
assert_turbo_stream_broadcasts [ users(:david), :rooms ], count: 2 do
|
||||
assert_changes -> { memberships(:david_watercooler).reload.involvement }, from: "invisible", to: "everything" do
|
||||
put room_involvement_url(rooms(:watercooler)), params: { involvement: "everything" }
|
||||
assert_redirected_to room_involvement_url(rooms(:watercooler))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "updating involvement does not send turbo update changing visible states" do
|
||||
assert_no_turbo_stream_broadcasts [ users(:david), :rooms ] do
|
||||
assert_changes -> { memberships(:david_watercooler).reload.involvement }, from: "everything", to: "mentions" do
|
||||
put room_involvement_url(rooms(:watercooler)), params: { involvement: "mentions" }
|
||||
assert_redirected_to room_involvement_url(rooms(:watercooler))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "updating involvement does not send turbo update for direct rooms" do
|
||||
assert_no_turbo_stream_broadcasts [ users(:david), :rooms ] do
|
||||
assert_changes -> { memberships(:david_david_and_jason).reload.involvement }, from: "everything", to: "nothing" do
|
||||
put room_involvement_url(rooms(:david_and_jason)), params: { involvement: "nothing" }
|
||||
assert_redirected_to room_involvement_url(rooms(:david_and_jason))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,51 @@
|
||||
require "test_helper"
|
||||
|
||||
class Rooms::OpensControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "show redirects to get general show" do
|
||||
get rooms_open_url(users(:david).rooms.opens.last)
|
||||
assert_redirected_to room_url(users(:david).rooms.opens.last)
|
||||
end
|
||||
|
||||
test "new" do
|
||||
get new_rooms_open_url
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "create" do
|
||||
assert_turbo_stream_broadcasts :rooms, count: 1 do
|
||||
post rooms_opens_url, params: { room: { name: "My New Room" } }
|
||||
end
|
||||
|
||||
assert_equal Room.last.memberships.count, User.count
|
||||
assert_redirected_to room_url(Room.last)
|
||||
end
|
||||
|
||||
test "only admins or creators can update" do
|
||||
sign_in :jz
|
||||
|
||||
assert_turbo_stream_broadcasts :rooms, count: 0 do
|
||||
put rooms_open_url(rooms(:hq)), params: { room: { name: "New Name" } }
|
||||
end
|
||||
|
||||
assert_response :forbidden
|
||||
assert rooms(:hq).reload.name, "HQ"
|
||||
end
|
||||
|
||||
test "update" do
|
||||
assert_turbo_stream_broadcasts :rooms, count: 1 do
|
||||
put rooms_open_url(rooms(:pets)), params: { room: { name: "New Name" } }
|
||||
end
|
||||
|
||||
assert_redirected_to room_url(rooms(:pets))
|
||||
assert rooms(:pets).reload.name, "New Name"
|
||||
end
|
||||
|
||||
test "update a closed room to be open" do
|
||||
put rooms_open_url(rooms(:designers)), params: { room: { name: "Doesn't matter" } }
|
||||
assert_equal rooms(:designers).memberships.count, User.count
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
require "test_helper"
|
||||
|
||||
class Rooms::RefreshesControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "refresh includes new messages since the last known" do
|
||||
travel_to 1.day.ago do
|
||||
@old_message = rooms(:hq).messages.create!(creator: users(:jason), body: "Old message", client_message_id: "old")
|
||||
end
|
||||
|
||||
travel_to 1.minute.ago do
|
||||
@new_message = rooms(:hq).messages.create!(creator: users(:jason), body: "New message", client_message_id: "new")
|
||||
@old_message.touch
|
||||
end
|
||||
|
||||
get room_refresh_url(rooms(:hq), format: :turbo_stream), params: { since: 10.minutes.ago.to_fs(:epoch) }
|
||||
|
||||
assert_response :success
|
||||
|
||||
assert_select "turbo-stream[action='append']" do
|
||||
assert_select "#" + dom_id(@new_message)
|
||||
assert_select "template", count: 1
|
||||
end
|
||||
|
||||
assert_select "turbo-stream[action='replace']" do
|
||||
assert_select "#" + dom_id(@old_message)
|
||||
assert_select "template", count: 1
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,45 @@
|
||||
require "test_helper"
|
||||
|
||||
class RoomsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "index redirects to the user's last room" do
|
||||
get rooms_url
|
||||
assert_redirected_to room_url(users(:david).rooms.last)
|
||||
end
|
||||
|
||||
test "show" do
|
||||
get room_url(users(:david).rooms.last)
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "shows records the last room visited in a cookie" do
|
||||
get room_url(users(:david).rooms.last)
|
||||
assert response.cookies[:last_room] = users(:david).rooms.last.id
|
||||
end
|
||||
|
||||
test "destroy" do
|
||||
assert_turbo_stream_broadcasts :rooms, count: 1 do
|
||||
assert_difference -> { Room.count }, -1 do
|
||||
delete room_url(rooms(:designers))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "destroy only allowed for creators or those who can administer" do
|
||||
sign_in :jz
|
||||
|
||||
assert_no_difference -> { Room.count } do
|
||||
delete room_url(rooms(:designers))
|
||||
assert_response :forbidden
|
||||
end
|
||||
|
||||
rooms(:designers).update! creator: users(:jz)
|
||||
|
||||
assert_difference -> { Room.count }, -1 do
|
||||
delete room_url(rooms(:designers))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,48 @@
|
||||
require "test_helper"
|
||||
|
||||
class SearchesControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
@message = rooms(:designers).messages.create! body: "Hello world!", client_message_id: "search", creator: users(:david)
|
||||
end
|
||||
|
||||
test "index initial view" do
|
||||
get searches_url
|
||||
|
||||
assert_response :success
|
||||
assert_select ".message", count: 0
|
||||
end
|
||||
|
||||
test "finding reachable messages" do
|
||||
get searches_url, params: { q: "hello" }
|
||||
|
||||
assert_response :success
|
||||
assert_select ".message", text: /Hello world!/
|
||||
end
|
||||
|
||||
test "unreachable messages are not found" do
|
||||
memberships(:david_designers).destroy!
|
||||
|
||||
get searches_url, params: { q: "hello" }
|
||||
|
||||
assert_response :success
|
||||
assert_select ".message", count: 0
|
||||
end
|
||||
|
||||
test "create saves the search term" do
|
||||
assert_difference -> { users(:david).searches.count }, +1 do
|
||||
post searches_url, params: { q: "hello" }
|
||||
end
|
||||
|
||||
assert_redirected_to searches_url(q: "hello")
|
||||
assert users(:david).searches.exists?(query: "hello")
|
||||
end
|
||||
|
||||
test "clear search history" do
|
||||
assert users(:david).searches.any?
|
||||
|
||||
delete clear_searches_url
|
||||
|
||||
assert users(:david).searches.none?
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
require "test_helper"
|
||||
|
||||
class Sessions::TransfersControllerTest < ActionDispatch::IntegrationTest
|
||||
test "show renders when not signed in" do
|
||||
get session_transfer_url("some-token")
|
||||
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "update establishes a session when the code is valid" do
|
||||
user = users(:david)
|
||||
|
||||
put session_transfer_url(user.transfer_id)
|
||||
|
||||
assert_redirected_to root_url
|
||||
assert parsed_cookies.signed[:session_token]
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,63 @@
|
||||
require "test_helper"
|
||||
|
||||
class SessionsControllerTest < ActionDispatch::IntegrationTest
|
||||
ALLOWED_BROWSER = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15"
|
||||
DISALLOWED_BROWSER = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0"
|
||||
|
||||
test "new" do
|
||||
get new_session_url
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "new redirects to first run when no users exist" do
|
||||
User.destroy_all
|
||||
|
||||
get new_session_url
|
||||
|
||||
assert_redirected_to first_run_url
|
||||
end
|
||||
|
||||
test "new denied with incompatible browser" do
|
||||
get new_session_url, env: { "HTTP_USER_AGENT" => DISALLOWED_BROWSER }
|
||||
assert_select "h1", /Upgrade to a supported web browser/
|
||||
end
|
||||
|
||||
test "new allowed with compatible browser" do
|
||||
get new_session_url, env: { "HTTP_USER_AGENT" => ALLOWED_BROWSER }
|
||||
assert_select "h1", text: /Upgrade to a supported web browser/, count: 0
|
||||
end
|
||||
|
||||
test "create with valid credentials" do
|
||||
post session_url, params: { email_address: "david@37signals.com", password: "secret123456" }
|
||||
|
||||
assert_redirected_to root_url
|
||||
assert parsed_cookies.signed[:session_token]
|
||||
end
|
||||
|
||||
test "create with invalid credentials" do
|
||||
post session_url, params: { email_address: "david@37signals.com", password: "wrong" }
|
||||
|
||||
assert_response :unauthorized
|
||||
assert_nil parsed_cookies.signed[:session_token]
|
||||
end
|
||||
|
||||
test "destroy" do
|
||||
sign_in :david
|
||||
|
||||
delete session_url
|
||||
|
||||
assert_redirected_to root_url
|
||||
assert_not cookies[:session_token].present?
|
||||
end
|
||||
|
||||
test "destroy removes the push subscription for the device" do
|
||||
sign_in :david
|
||||
|
||||
assert_difference -> { users(:david).push_subscriptions.count }, -1 do
|
||||
delete session_url, params: { push_subscription_endpoint: push_subscriptions(:david_chrome).endpoint }
|
||||
end
|
||||
|
||||
assert_redirected_to root_url
|
||||
assert_not cookies[:session_token].present?
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,64 @@
|
||||
require "test_helper"
|
||||
|
||||
class UnfurlLinksControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "create" do
|
||||
stub_successful_request
|
||||
|
||||
post unfurl_link_url, params: { url: "https://www.example.com" }
|
||||
assert_response :success
|
||||
|
||||
json_response = JSON.parse(response.body)
|
||||
assert_equal "Hey!", json_response["title"]
|
||||
assert_equal "https://example.com", json_response["url"]
|
||||
assert_equal "https://example.com/image.png", json_response["image"]
|
||||
assert_equal "desc..", json_response["description"]
|
||||
end
|
||||
|
||||
test "create with missing opengraph meta tags" do
|
||||
WebMock.stub_request(:get, "https://www.example.com/").to_return(status: 200, body: "<html><head></head></html>", headers: {})
|
||||
|
||||
post unfurl_link_url, params: { url: "https://www.example.com" }
|
||||
assert_response :no_content
|
||||
end
|
||||
|
||||
test "create with a missing URL" do
|
||||
assert_raise ActionController::ParameterMissing do
|
||||
post unfurl_link_url, params: { url: "" }
|
||||
assert_response :bad_request
|
||||
end
|
||||
end
|
||||
|
||||
test "create for twitter.com" do
|
||||
stub_successful_request url: "https://fxtwitter.com/dhh/status/834146806594433025"
|
||||
|
||||
post unfurl_link_url, params: { url: "https://twitter.com/dhh/status/834146806594433025" }
|
||||
assert_response :success
|
||||
assert_equal "Hey!", JSON.parse(response.body)["title"]
|
||||
end
|
||||
|
||||
test "create for x.com" do
|
||||
stub_successful_request url: "https://fxtwitter.com/dhh/status/834146806594433025"
|
||||
|
||||
post unfurl_link_url, params: { url: "https://x.com/dhh/status/834146806594433025" }
|
||||
assert_response :success
|
||||
assert_equal "Hey!", JSON.parse(response.body)["title"]
|
||||
end
|
||||
|
||||
private
|
||||
def stub_successful_request(url: "https://www.example.com/")
|
||||
WebMock.stub_request(:get, url).to_return(
|
||||
status: 200,
|
||||
body: "<html><head><meta property=\"og:url\" content=\"https://example.com\"><meta property=\"og:title\" content=\"Hey!\"><meta property=\"og:description\" content=\"desc..\"><meta property=\"og:image\" content=\"https://example.com/image.png\"></head></html>",
|
||||
headers: { content_type: "text/html" }
|
||||
)
|
||||
|
||||
WebMock.stub_request(:head, "https://example.com/image.png").to_return(
|
||||
status: 200,
|
||||
headers: { content_type: "image/png" }
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
require "test_helper"
|
||||
|
||||
class Users::AvatarsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "show initials" do
|
||||
get user_avatar_url(users(:kevin).avatar_token)
|
||||
assert_select "text", text: "K"
|
||||
end
|
||||
|
||||
test "show image" do
|
||||
users(:kevin).update! avatar: fixture_file_upload("moon.jpg", "image/jpeg")
|
||||
get user_avatar_url(users(:kevin).avatar_token)
|
||||
|
||||
assert_response :success
|
||||
assert_equal "image/webp", @response.content_type
|
||||
end
|
||||
|
||||
test "show image with invalid token responds 404" do
|
||||
get user_avatar_url("not-a-valid-token")
|
||||
|
||||
assert_response :not_found
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,28 @@
|
||||
require "test_helper"
|
||||
|
||||
class Users::ProfilesControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "show" do
|
||||
get user_profile_url
|
||||
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "update" do
|
||||
put user_profile_url, params: { user: { name: "John Doe", bio: "Acrobat" } }
|
||||
|
||||
assert_redirected_to user_profile_url
|
||||
assert_equal "John Doe", users(:david).reload.name
|
||||
assert_equal "Acrobat", users(:david).bio
|
||||
assert_equal "david@37signals.com", users(:david).email_address
|
||||
end
|
||||
|
||||
test "updates are limited to the current user" do
|
||||
put user_profile_url(users(:jason)), params: { user: { name: "John Doe" } }
|
||||
|
||||
assert_equal "Jason", users(:jason).reload.name
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,38 @@
|
||||
require "test_helper"
|
||||
|
||||
class Users::PushSubscriptionsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "create new push subscription" do
|
||||
subscription_params = { "endpoint" => "https://apple", "p256dh_key" => "123", "auth_key" => "456" }
|
||||
|
||||
post user_push_subscriptions_url,
|
||||
params: { push_subscription: subscription_params }, headers: { "HTTP_USER_AGENT" => "Mozilla/5.0" }
|
||||
|
||||
assert_response :ok
|
||||
|
||||
assert_equal subscription_params, users(:david).push_subscriptions.last.attributes.slice("endpoint", "p256dh_key", "auth_key")
|
||||
assert_equal "Mozilla/5.0", users(:david).push_subscriptions.last.user_agent
|
||||
end
|
||||
|
||||
test "touch existing subscription" do
|
||||
assert_no_difference -> { users(:david).push_subscriptions.count } do
|
||||
assert_changes -> { push_subscriptions(:david_chrome).reload.updated_at } do
|
||||
post user_push_subscriptions_url(params: {
|
||||
push_subscription: push_subscriptions(:david_chrome).attributes.slice("endpoint", "p256dh_key", "auth_key")
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
assert_response :ok
|
||||
end
|
||||
|
||||
test "destroy a push subscription via dev mode" do
|
||||
assert_difference -> { Push::Subscription.count }, -1 do
|
||||
delete user_push_subscription_url(push_subscriptions(:david_chrome))
|
||||
assert_redirected_to user_push_subscriptions_url
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
require "test_helper"
|
||||
|
||||
class Users::SidebarsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "show" do
|
||||
get user_sidebar_url
|
||||
|
||||
users(:david).rooms.opens.each do |room|
|
||||
assert_match /#{room.name}/, @response.body
|
||||
end
|
||||
end
|
||||
|
||||
test "unread directs" do
|
||||
rooms(:david_and_jason).messages.create! client_message_id: 999, body: "Hello", creator: users(:jason)
|
||||
|
||||
get user_sidebar_url
|
||||
assert_select ".unread", count: users(:david).memberships.select { |m| m.room.direct? && m.unread? }.count
|
||||
end
|
||||
|
||||
|
||||
test "unread other" do
|
||||
rooms(:watercooler).messages.create! client_message_id: 999, body: "Hello", creator: users(:jason)
|
||||
|
||||
get user_sidebar_url
|
||||
assert_select ".unread", count: users(:david).memberships.reject { |m| m.room.direct? || !m.unread? }.count
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,50 @@
|
||||
require "test_helper"
|
||||
|
||||
class UsersControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
@join_code = accounts(:signal).join_code
|
||||
end
|
||||
|
||||
test "show" do
|
||||
sign_in :david
|
||||
get user_url(users(:david))
|
||||
assert_response :ok
|
||||
end
|
||||
|
||||
test "new" do
|
||||
get join_url(@join_code)
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "new does not allow a signed in user" do
|
||||
sign_in :david
|
||||
|
||||
get join_url(@join_code)
|
||||
assert_redirected_to root_url
|
||||
end
|
||||
|
||||
test "new requires a join code" do
|
||||
get join_url("not")
|
||||
assert_response :not_found
|
||||
end
|
||||
|
||||
test "create" do
|
||||
assert_difference -> { User.count }, 1 do
|
||||
post join_url(@join_code), params: { user: { name: "New Person", email_address: "new@37signals.com", password: "secret123456" } }
|
||||
end
|
||||
|
||||
assert_redirected_to root_url
|
||||
|
||||
user = User.last
|
||||
assert_equal user.id, Session.find_by(token: parsed_cookies.signed[:session_token]).user.id
|
||||
assert_equal Rooms::Open.all, user.rooms
|
||||
end
|
||||
|
||||
test "creating a new user with an existing email address will redirect to login screen" do
|
||||
assert_no_difference -> { User.count } do
|
||||
post join_url(@join_code), params: { user: { name: "Another David", email_address: users(:david).email_address, password: "secret123456" } }
|
||||
end
|
||||
|
||||
assert_redirected_to new_session_url(email_address: users(:david).email_address)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,21 @@
|
||||
require "test_helper"
|
||||
|
||||
class WelcomeControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in :david
|
||||
end
|
||||
|
||||
test "redirects to the first created visible room the user has access to" do
|
||||
get root_url
|
||||
|
||||
assert_redirected_to room_url(users(:david).rooms.original)
|
||||
end
|
||||
|
||||
test "redirects to the last room visited, if we have one" do
|
||||
cookies[:last_room] = rooms(:watercooler).id
|
||||
|
||||
get root_url
|
||||
|
||||
assert_redirected_to room_url(rooms(:watercooler))
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user