mirror of
https://github.com/we-promise/sure.git
synced 2026-09-06 23:24:21 +00:00
Add experimental Swift-native Sure Insights app (#3134)
* Add Swift-native Sure app * Fix push subscriptions schema for CI * Address native app review feedback * Address remaining native app review feedback * Use Flutter app logo for native icon * Honor insight notification preferences and locale --------- Co-authored-by: Juan Jose Mata <2v8shcb6pz@privaterelay.appleid.com> Co-authored-by: sure-admin <sure-admin@splashblot.com>
This commit is contained in:
co-authored by
Juan Jose Mata
sure-admin
parent
311f06e404
commit
0aa43de10a
@@ -0,0 +1,160 @@
|
||||
require "test_helper"
|
||||
|
||||
class Api::V1::PushSubscriptionsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
@user = users(:family_admin)
|
||||
key = ApiKey.generate_secure_key
|
||||
@api_key = ApiKey.create!(
|
||||
user: @user,
|
||||
name: "Native push test",
|
||||
key: key,
|
||||
scopes: [ "read_write" ],
|
||||
source: "mobile"
|
||||
)
|
||||
@headers = api_headers(@api_key)
|
||||
@token = "ab" * 32
|
||||
end
|
||||
|
||||
test "registers and refreshes an APNs token" do
|
||||
assert_difference "PushSubscription.count", 1 do
|
||||
post api_v1_push_subscriptions_url,
|
||||
params: { token: @token, environment: "sandbox", platform: "ios" },
|
||||
headers: @headers,
|
||||
as: :json
|
||||
end
|
||||
|
||||
assert_response :created
|
||||
subscription = PushSubscription.find_by!(token: @token)
|
||||
assert_equal @user, subscription.user
|
||||
assert_equal "sandbox", subscription.environment
|
||||
|
||||
assert_no_difference "PushSubscription.count" do
|
||||
post api_v1_push_subscriptions_url,
|
||||
params: { token: @token, environment: "production", platform: "ios" },
|
||||
headers: @headers,
|
||||
as: :json
|
||||
end
|
||||
assert_equal "production", subscription.reload.environment
|
||||
end
|
||||
|
||||
test "requires a read write API key" do
|
||||
read_key_value = ApiKey.generate_secure_key
|
||||
read_key = ApiKey.create!(
|
||||
user: @user,
|
||||
name: "Read-only native push test",
|
||||
key: read_key_value,
|
||||
scopes: [ "read" ],
|
||||
source: "mobile"
|
||||
)
|
||||
|
||||
post api_v1_push_subscriptions_url,
|
||||
params: { token: @token, environment: "sandbox", platform: "ios" },
|
||||
headers: api_headers(read_key),
|
||||
as: :json
|
||||
|
||||
assert_response :forbidden
|
||||
end
|
||||
|
||||
test "rejects malformed tokens" do
|
||||
post api_v1_push_subscriptions_url,
|
||||
params: { token: "not-a-device-token", environment: "sandbox", platform: "ios" },
|
||||
headers: @headers,
|
||||
as: :json
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
end
|
||||
|
||||
test "rejects an invalid APNs environment" do
|
||||
post api_v1_push_subscriptions_url,
|
||||
params: { token: @token, environment: "staging", platform: "ios" },
|
||||
headers: @headers,
|
||||
as: :json
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
end
|
||||
|
||||
test "normalizes APNs tokens before lookup and persistence" do
|
||||
post api_v1_push_subscriptions_url,
|
||||
params: { token: @token.upcase, environment: "sandbox", platform: "ios" },
|
||||
headers: @headers,
|
||||
as: :json
|
||||
|
||||
assert_response :created
|
||||
assert PushSubscription.exists?(token: @token)
|
||||
|
||||
assert_no_difference "PushSubscription.count" do
|
||||
post api_v1_push_subscriptions_url,
|
||||
params: { token: @token, environment: "sandbox", platform: "ios" },
|
||||
headers: @headers,
|
||||
as: :json
|
||||
end
|
||||
end
|
||||
|
||||
test "does not transfer another user's token" do
|
||||
other_user = users(:empty)
|
||||
subscription = other_user.push_subscriptions.create!(
|
||||
token: @token,
|
||||
environment: "sandbox",
|
||||
platform: "ios",
|
||||
last_registered_at: Time.current
|
||||
)
|
||||
|
||||
post api_v1_push_subscriptions_url,
|
||||
params: { token: @token.upcase, environment: "production", platform: "ios" },
|
||||
headers: @headers,
|
||||
as: :json
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal other_user, subscription.reload.user
|
||||
assert_equal "sandbox", subscription.environment
|
||||
end
|
||||
|
||||
test "returns a controlled response when concurrent token registration conflicts" do
|
||||
PushSubscription.any_instance.stubs(:save!).raises(ActiveRecord::RecordNotUnique)
|
||||
|
||||
post api_v1_push_subscriptions_url,
|
||||
params: { token: @token, environment: "sandbox", platform: "ios" },
|
||||
headers: @headers,
|
||||
as: :json
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal "validation_error", response.parsed_body["error"]
|
||||
end
|
||||
|
||||
test "removes the current user's token" do
|
||||
subscription = @user.push_subscriptions.create!(
|
||||
token: @token,
|
||||
environment: "sandbox",
|
||||
platform: "ios",
|
||||
last_registered_at: Time.current
|
||||
)
|
||||
|
||||
assert_difference "PushSubscription.count", -1 do
|
||||
delete api_v1_push_subscription_url(subscription), headers: @headers
|
||||
end
|
||||
|
||||
assert_response :no_content
|
||||
end
|
||||
|
||||
test "does not remove another user's token" do
|
||||
subscription = users(:empty).push_subscriptions.create!(
|
||||
token: @token,
|
||||
environment: "sandbox",
|
||||
platform: "ios",
|
||||
last_registered_at: Time.current
|
||||
)
|
||||
|
||||
delete api_v1_push_subscription_url(subscription), headers: @headers
|
||||
|
||||
assert_response :not_found
|
||||
assert PushSubscription.exists?(subscription.id)
|
||||
end
|
||||
|
||||
test "requires authentication" do
|
||||
post api_v1_push_subscriptions_url,
|
||||
params: { token: @token, environment: "sandbox", platform: "ios" },
|
||||
as: :json
|
||||
|
||||
assert_response :unauthorized
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user