Merge pull request #2599 from basecamp/mobile/path-config-setup

Mobile: Path config endpoint
This commit is contained in:
Denis Svara
2026-02-24 14:52:09 +01:00
committed by GitHub
5 changed files with 245 additions and 0 deletions
@@ -0,0 +1,15 @@
class ClientConfigurationsController < ApplicationController
skip_before_action :require_account, :require_authentication
allow_unauthorized_access
def show
expires_in 1.minute, public: true
render action: client_configuration_name
end
private
def client_configuration_name
"#{params.require(:platform)}_v#{params.require(:version)}"
end
end
@@ -0,0 +1,90 @@
{
"settings": {},
"rules": [
{
"patterns": [
".*"
],
"properties": {
"context": "default",
"presentation": "default",
"query_string_presentation": "replace",
"uri": "hotwire://fragment/web",
"fallback_uri": "hotwire://fragment/web",
"pull_to_refresh_enabled": true
}
},
{
"patterns": [
"/new$",
"/new\\?.+$",
"/edit$",
"/edit\\?.+$",
"/cards/[0-9]+/draft",
"/notifications/settings",
"/account/settings",
"/account/join_code"
],
"properties": {
"context": "modal",
"pull_to_refresh_enabled": false
}
},
{
"patterns": [
"/native/login/blank"
],
"properties": {
"uri": "hotwire://fragment/login/blank"
}
},
{
"patterns": [
"/native/login/email"
],
"properties": {
"uri": "hotwire://fragment/login/email"
}
},
{
"patterns": [
"/native/login/magic_code"
],
"properties": {
"uri": "hotwire://fragment/login/magic_code"
}
},
{
"patterns": [
"/native/login/signup_completion"
],
"properties": {
"uri": "hotwire://fragment/login/signup_completion"
}
},
{
"patterns": [
"/native/settings"
],
"properties": {
"uri": "hotwire://fragment/settings"
}
},
{
"patterns": [
"/my/pins"
],
"properties": {
"uri": "hotwire://fragment/pins"
}
},
{
"patterns": [
"/notifications$"
],
"properties": {
"uri": "hotwire://fragment/notifications"
}
}
]
}
@@ -0,0 +1,89 @@
{
"settings": {
},
"rules": [
{
"patterns": [
".*"
],
"properties": {
"context": "default",
"query_string_presentation": "replace",
"pull_to_refresh_enabled": true
}
},
{
"patterns": [
"/new$",
"/new\\?.+$",
"/edit$",
"/edit\\?.+$",
"/accounts$",
"/cards/[0-9]+/draft"
],
"properties": {
"context": "modal",
"pull_to_refresh_enabled": false
}
},
{
"patterns": [
"/native/my_menu$"
],
"properties": {
"context": "modal",
"view_controller": "main_menu"
}
},
{
"patterns": [
"/native/add_account$"
],
"properties": {
"context": "modal",
"view_controller": "login"
}
},
{
"patterns": [
"/native/login$"
],
"properties": {
"view_controller": "login"
}
},
{
"patterns": [
"/my/pins$"
],
"properties": {
"view_controller": "pinned"
}
},
{
"patterns": [
"/notifications/tray$"
],
"properties": {
"view_controller": "notifications"
}
},
{
"patterns": [
"internal/devtools/enable*"
],
"properties": {
"context": "modal",
"view_controller": "dev_settings_launcher"
}
},
{
"patterns": [
"/native/settings$"
],
"properties": {
"view_controller": "settings"
}
}
]
}
+4
View File
@@ -245,6 +245,10 @@ Rails.application.routes.draw do
get "manifest" => "rails/pwa#manifest", as: :pwa_manifest
get "service-worker" => "pwa#service_worker"
# Mobile clients
get "client_configurations/(:platform)_v(:version)" => "client_configurations#show",
platform: /android|ios/, version: /\d+/
namespace :admin do
mount MissionControl::Jobs::Engine, at: "/jobs"
end
@@ -0,0 +1,47 @@
require "test_helper"
class ClientConfigurationsControllerTest < ActionDispatch::IntegrationTest
test "android" do
assert_ok "/client_configurations/android_v1.json"
end
test "ios" do
assert_ok "/client_configurations/ios_v1.json"
end
test "bad platform" do
assert_no_route "/client_configurations/blackberry_v1.json"
end
test "bad version" do
assert_no_route "/client_configurations/android_va.json"
end
test "nonexistent version" do
assert_missing "/client_configurations/android_v2000.json"
assert_missing "/client_configurations/ios_v2000.json"
end
private
def assert_ok(url, cache_control: { public: true, max_age: "60" })
get url
assert_response :ok
assert_kind_of Hash, response.parsed_body["settings"]
assert_kind_of Array, response.parsed_body["rules"]
assert_equal cache_control, response.cache_control
end
def assert_no_route(url)
without_action_dispatch_exception_handling do
assert_raises(ActionController::RoutingError) { get url }
end
end
def assert_missing(url)
without_action_dispatch_exception_handling do
assert_raises(ActionView::MissingTemplate) { get url }
end
end
end