Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/stacks/forecast.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class Stacks::Forecast
include HTTParty
base_uri 'api.forecastapp.com'
base_uri 'https://api.forecastapp.com'

def initialize()
@headers = {
Expand Down
2 changes: 1 addition & 1 deletion lib/stacks/twist.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class Stacks::Twist
include HTTParty
base_uri 'api.twist.com/api/v3'
base_uri 'https://api.twist.com/api/v3'

def initialize()
@headers = {
Expand Down
30 changes: 30 additions & 0 deletions test/lib/stacks/https_base_uri_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require "test_helper"

# Regression guard for a silent, production-only class of bug:
#
# A scheme-less HTTParty `base_uri` (e.g. "api.forecastapp.com") defaults to
# http://. Forecast (and Twist) 301-redirect http -> https. GETs survive the
# redirect, but a redirected POST/PUT/DELETE arrives malformed and the API
# returns 400 — so READS work while WRITES silently fail. Stubbed unit tests
# never catch it because they don't hit the network; it only surfaces against
# the live API. `Stacks::Forecast#create_assignment` hitting this is exactly
# what stopped recurring-assignment materialization from reaching Forecast.
#
# Pin every HTTParty API client to an explicit https base_uri.
class Stacks::HttpsBaseUriTest < ActiveSupport::TestCase
CLIENTS = [
Stacks::Forecast,
Stacks::Twist,
Stacks::Runn,
Stacks::Deel,
Stacks::Notion,
Stacks::Apollo,
].freeze

test "every HTTParty API client uses an https base_uri (writes must not ride an http->https redirect)" do
CLIENTS.each do |klass|
assert klass.base_uri.to_s.start_with?("https://"),
"#{klass}.base_uri must be https to avoid write-mangling redirects; got #{klass.base_uri.inspect}"
end
end
end