53df0e405b
Keep legacy /devices routes for backwards compatibility with mobile apps not yet updated. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
258 lines
6.5 KiB
Ruby
258 lines
6.5 KiB
Ruby
require "test_helper"
|
|
|
|
class My::DevicesControllerTest < ActionDispatch::IntegrationTest
|
|
setup do
|
|
@identity = identities(:david)
|
|
sign_in_as :david
|
|
end
|
|
|
|
test "index shows identity's devices" do
|
|
@identity.devices.create!(token: "test_token_123", platform: "apple", name: "iPhone 15 Pro")
|
|
|
|
untenanted { get saas.my_devices_path }
|
|
|
|
assert_response :success
|
|
assert_select "strong", "iPhone 15 Pro"
|
|
assert_select "li", /iOS/
|
|
end
|
|
|
|
test "index shows empty state when no devices" do
|
|
@identity.devices.delete_all
|
|
|
|
untenanted { get saas.my_devices_path }
|
|
|
|
assert_response :success
|
|
assert_select "h1", /No devices registered/
|
|
end
|
|
|
|
test "show notification settings with registered devices" do
|
|
@identity.devices.create!(token: "test_token", platform: "apple", name: "iPhone 15 Pro")
|
|
|
|
get notifications_settings_path
|
|
|
|
assert_response :success
|
|
end
|
|
|
|
test "index requires authentication" do
|
|
sign_out
|
|
|
|
untenanted { get saas.my_devices_path }
|
|
|
|
assert_response :redirect
|
|
end
|
|
|
|
test "creates a new device via api" do
|
|
token = SecureRandom.hex(32)
|
|
|
|
assert_difference -> { ApplicationPushDevice.count }, 1 do
|
|
untenanted do
|
|
post saas.my_devices_path, params: {
|
|
token: token,
|
|
platform: "apple",
|
|
name: "iPhone 15 Pro"
|
|
}, as: :json
|
|
end
|
|
end
|
|
|
|
assert_response :created
|
|
|
|
device = ApplicationPushDevice.last
|
|
assert_equal token, device.token
|
|
assert_equal "apple", device.platform
|
|
assert_equal "iPhone 15 Pro", device.name
|
|
assert_equal @identity, device.owner
|
|
end
|
|
|
|
test "creates android device" do
|
|
untenanted do
|
|
post saas.my_devices_path, params: {
|
|
token: SecureRandom.hex(32),
|
|
platform: "google",
|
|
name: "Pixel 8"
|
|
}, as: :json
|
|
end
|
|
|
|
assert_response :created
|
|
|
|
device = ApplicationPushDevice.last
|
|
assert_equal "google", device.platform
|
|
end
|
|
|
|
test "same token can be registered by multiple identities" do
|
|
shared_token = "shared_push_token_123"
|
|
other_identity = identities(:kevin)
|
|
|
|
# Other identity registers the token first
|
|
other_device = other_identity.devices.create!(
|
|
token: shared_token,
|
|
platform: "apple",
|
|
name: "Kevin's iPhone"
|
|
)
|
|
|
|
# Current identity registers the same token with their own device
|
|
assert_difference -> { ApplicationPushDevice.count }, 1 do
|
|
untenanted do
|
|
post saas.my_devices_path, params: {
|
|
token: shared_token,
|
|
platform: "apple",
|
|
name: "David's iPhone"
|
|
}, as: :json
|
|
end
|
|
end
|
|
|
|
assert_response :created
|
|
|
|
# Both identities have their own device records
|
|
assert_equal shared_token, other_device.reload.token
|
|
assert_equal other_identity, other_device.owner
|
|
|
|
davids_device = @identity.devices.last
|
|
assert_equal shared_token, davids_device.token
|
|
assert_equal @identity, davids_device.owner
|
|
end
|
|
|
|
test "rejects invalid platform" do
|
|
untenanted do
|
|
post saas.my_devices_path, params: {
|
|
token: SecureRandom.hex(32),
|
|
platform: "windows",
|
|
name: "Surface"
|
|
}, as: :json
|
|
end
|
|
|
|
assert_response :unprocessable_entity
|
|
end
|
|
|
|
test "rejects missing token" do
|
|
untenanted do
|
|
post saas.my_devices_path, params: {
|
|
platform: "apple",
|
|
name: "iPhone"
|
|
}, as: :json
|
|
end
|
|
|
|
assert_response :bad_request
|
|
end
|
|
|
|
test "create requires authentication" do
|
|
sign_out
|
|
|
|
untenanted do
|
|
post saas.my_devices_path, params: {
|
|
token: SecureRandom.hex(32),
|
|
platform: "apple"
|
|
}, as: :json
|
|
end
|
|
|
|
assert_response :redirect
|
|
end
|
|
|
|
test "destroys device by id" do
|
|
device = @identity.devices.create!(
|
|
token: "token_to_delete",
|
|
platform: "apple",
|
|
name: "iPhone"
|
|
)
|
|
|
|
assert_difference -> { ApplicationPushDevice.count }, -1 do
|
|
untenanted { delete saas.my_device_path(device) }
|
|
end
|
|
|
|
assert_redirected_to saas.my_devices_path(script_name: nil)
|
|
assert_not ApplicationPushDevice.exists?(device.id)
|
|
end
|
|
|
|
test "returns not found when device not found by id" do
|
|
assert_no_difference "ApplicationPushDevice.count" do
|
|
untenanted { delete saas.my_device_path(id: "nonexistent") }
|
|
end
|
|
|
|
assert_response :not_found
|
|
end
|
|
|
|
test "returns not found for another identity's device by id" do
|
|
other_identity = identities(:kevin)
|
|
device = other_identity.devices.create!(
|
|
token: "other_identity_token",
|
|
platform: "apple",
|
|
name: "Other iPhone"
|
|
)
|
|
|
|
assert_no_difference "ApplicationPushDevice.count" do
|
|
untenanted { delete saas.my_device_path(device) }
|
|
end
|
|
|
|
assert_response :not_found
|
|
assert ApplicationPushDevice.exists?(device.id)
|
|
end
|
|
|
|
test "destroy by id requires authentication" do
|
|
device = @identity.devices.create!(
|
|
token: "my_token",
|
|
platform: "apple",
|
|
name: "iPhone"
|
|
)
|
|
|
|
sign_out
|
|
|
|
untenanted { delete saas.my_device_path(device) }
|
|
|
|
assert_response :redirect
|
|
assert ApplicationPushDevice.exists?(device.id)
|
|
end
|
|
|
|
test "destroys device by token" do
|
|
device = @identity.devices.create!(
|
|
token: "token_to_unregister",
|
|
platform: "apple",
|
|
name: "iPhone"
|
|
)
|
|
|
|
assert_difference -> { ApplicationPushDevice.count }, -1 do
|
|
untenanted { delete saas.my_device_path("token_to_unregister"), as: :json }
|
|
end
|
|
|
|
assert_response :no_content
|
|
assert_not ApplicationPushDevice.exists?(device.id)
|
|
end
|
|
|
|
test "returns not found when device not found by token" do
|
|
assert_no_difference "ApplicationPushDevice.count" do
|
|
untenanted { delete saas.my_device_path("nonexistent_token"), as: :json }
|
|
end
|
|
|
|
assert_response :not_found
|
|
end
|
|
|
|
test "returns not found for another identity's device by token" do
|
|
other_identity = identities(:kevin)
|
|
device = other_identity.devices.create!(
|
|
token: "other_identity_token",
|
|
platform: "apple",
|
|
name: "Other iPhone"
|
|
)
|
|
|
|
assert_no_difference "ApplicationPushDevice.count" do
|
|
untenanted { delete saas.my_device_path("other_identity_token"), as: :json }
|
|
end
|
|
|
|
assert_response :not_found
|
|
assert ApplicationPushDevice.exists?(device.id)
|
|
end
|
|
|
|
test "destroy by token requires authentication" do
|
|
device = @identity.devices.create!(
|
|
token: "my_token",
|
|
platform: "apple",
|
|
name: "iPhone"
|
|
)
|
|
|
|
sign_out
|
|
|
|
untenanted { delete saas.my_device_path("my_token"), as: :json }
|
|
|
|
assert_response :redirect
|
|
assert ApplicationPushDevice.exists?(device.id)
|
|
end
|
|
end
|