Merge branch 'main' into bundle-emails

This commit is contained in:
Jorge Manrubia
2025-08-27 10:17:32 +02:00
60 changed files with 2859 additions and 291 deletions
+7 -3
View File
@@ -33,15 +33,19 @@ class Ai::ListCardsToolTest < ActiveSupport::TestCase
end
test "execute when filtering by ids" do
creating_card = collections(:writebook).cards.create! creator: users(:kevin), status: :creating
drafted_card = collections(:writebook).cards.create! creator: users(:kevin), status: :drafted
cards = cards(:shipping, :logo)
card_ids = cards.pluck(:id)
visible_card_ids = cards.pluck(:id)
card_ids = visible_card_ids + [ creating_card.id, drafted_card.id ]
response = @tool.execute(ids: card_ids.join(", "))
page = parse_paginated_response(response)
record_ids = page[:records].map { |card| card["id"].to_i }
assert_equal 2, record_ids.count
assert_equal card_ids.sort, record_ids.sort
assert_equal visible_card_ids.count, record_ids.count
assert_equal visible_card_ids.sort, record_ids.sort
end
test "execute when filtering by collection_ids" do
+40
View File
@@ -0,0 +1,40 @@
require "test_helper"
class Ai::Quota::MoneyTest < ActiveSupport::TestCase
test "wrapping" do
money = Ai::Quota::Money.wrap("$5.42")
assert_equal 5_42_000_000, money.in_microcents, "Strings with numbers are treated as dollars"
assert_raises TypeError do
Ai::Quota::Money.wrap("foobar")
end
money = Ai::Quota::Money.wrap(5.42)
assert_equal 5_42_000_000, money.in_microcents, "Decimals are treated as dollars"
money = Ai::Quota::Money.wrap(5)
assert_equal 5, money.in_microcents, "Integers are treated as microcents"
money1 = Ai::Quota::Money.wrap("$5")
money2 = Ai::Quota::Money.wrap(money1)
assert_equal money1, money2, "Money can wrap itself"
assert_raises ArgumentError do
Ai::Quota::Money.wrap(nil)
end
end
test "conversions" do
money = Ai::Quota::Money.wrap("$0")
assert_equal 0.0, money.in_dollars
assert_equal 0, money.in_microcents
money = Ai::Quota::Money.wrap("$1")
assert_equal 1, money.in_dollars
assert_equal 1_00_000_000, money.in_microcents
money = Ai::Quota::Money.wrap("$5.42")
assert_equal 5.42, money.in_dollars
assert_equal 5_42_000_000, money.in_microcents
end
end
+63
View File
@@ -0,0 +1,63 @@
require "test_helper"
class Ai::QuotaTest < ActiveSupport::TestCase
setup do
@quota = Ai::Quota.new(user: users(:jz), limit: Ai::Quota::Money.wrap("$100").in_microcents)
end
test "create" do
assert @quota.save
assert_in_delta 7.days.from_now, @quota.reset_at, 1.minute
assert_equal 0, @quota.used
assert_equal Ai::Quota::Money.wrap("$100").in_microcents, @quota.limit
end
test "increment usage" do
@quota.save
@quota.spend("$100")
assert_equal Ai::Quota::Money.wrap("$100").in_microcents, @quota.used
@quota.spend("$500")
assert_equal Ai::Quota::Money.wrap("$600").in_microcents, @quota.used
@quota.spend("$1000")
assert_equal Ai::Quota::Money.wrap("$1600").in_microcents, @quota.used
@quota.spend("$5000")
assert_equal Ai::Quota::Money.wrap("$6600").in_microcents, @quota.used
@quota.spend("$10000")
assert_equal Ai::Quota::Money.wrap("$16600").in_microcents, @quota.used
@quota.used = 0
@quota.spend("$10")
assert_equal Ai::Quota::Money.wrap("$10").in_microcents, @quota.used
assert_in_delta 7.days.from_now, @quota.reset_at, 1.minute
travel 2.days
@quota.spend("$5")
assert_equal Ai::Quota::Money.wrap("$15").in_microcents, @quota.used
assert_in_delta 5.days.from_now, @quota.reset_at, 1.minute
travel 8.days
@quota.spend("$5")
assert_equal Ai::Quota::Money.wrap("$5").in_microcents, @quota.used
assert_in_delta 7.days.from_now, @quota.reset_at, 1.minute
end
test "limit checks" do
@quota.save
@quota.used = 0
@quota.ensure_not_depleted
@quota.used = Ai::Quota::Money.wrap("$300").in_microcents
assert_raises Ai::Quota::UsageExceedsQuotaError do
@quota.ensure_not_depleted
end
travel 10.days
@quota.ensure_not_depleted
end
end
@@ -13,23 +13,20 @@ class Conversation::Message::ResponseGenerator::ResponseTest < ActiveSupport::Te
# and 60 USD per million output tokens
# That's 0.00003 cents per input token and 0.00006 cents
# per output token
# Which is 3 micro-cents per input token and 6 micro-cents
# Which is 3000 micro-cents per input token and 6000 micro-cents
# per output token
assert_equal "3.0".to_d, response.input_token_price_microcents
assert_equal "6.0".to_d, response.output_token_price_microcents
assert_equal "3000.0".to_d, response.input_token_price_microcents
assert_equal "6000.0".to_d, response.output_token_price_microcents
# We've got 198 input tokens, so that's
# 193 * 3 = 594
assert_equal 594, response.input_cost_microcents
# 198 * 3000 = 594000
assert_equal 594000, response.input_cost_in_microcents
# We've got 2 output tokens, so that's
# 2 * 6 = 12
assert_equal 12, response.output_cost_microcents
# 2 * 6000 = 12
assert_equal 12000, response.output_cost_in_microcents
# So the total is 594 + 12 micro-cents
assert_equal 606, response.cost_microcents
# If we convert that to a decimal value we get 0.00606 cents
assert_equal "0.00606".to_d, response.cost
# So the total is 594000 + 12000 micro-cents
assert_equal 606000, response.cost_in_microcents
end
end
+14 -10
View File
@@ -61,21 +61,25 @@ class ConversationTest < ActiveSupport::TestCase
assert conversation.ready?, "The conversation should switch back to ready after a response is made"
end
test "clearing conversation messages" do
test "cost limits" do
conversation = conversations(:kevin)
assert conversation.messages.any?, "The conversation should have messages before clearing"
conversation.ask("Where does the planning office keep demolition notices?")
conversation.respond(
"In a locked filing cabinet in a disused lavatory",
cost_in_microcents: Ai::Quota::Money.wrap("$3").in_microcents
)
original_updated_at = conversation.updated_at
conversation.clear
assert conversation.updated_at > original_updated_at, "The conversation's updated_at timestamp should change after clearing messages"
conversation.ask("What's the meaning of life?")
conversation.respond("42", cost_in_microcents: Ai::Quota::Money.wrap("$120").in_microcents)
assert conversation.messages.empty?, "All messages should be deleted when clearing the conversation"
end
assert_raises Ai::Quota::UsageExceedsQuotaError do
conversation.ask("Should you leave a house without a towel?")
end
test "cost calculation" do
conversation = conversations(:kevin)
travel 1.month
assert_equal "0.01053".to_d, conversation.cost
conversation.ask("Should you leave a house without a towel?")
conversation.respond("Never", cost_in_microcents: Ai::Quota::Money.wrap("$0.01").in_microcents)
end
end
+1 -1
View File
@@ -28,6 +28,6 @@ class Event::ActivitySummaryTest < ActiveSupport::TestCase
test "getting an HTML summary for a set of events" do
summary = Event::ActivitySummary.create_for(@events)
assert_includes summary.to_html, "layout"
assert_match /layout/i, summary.to_html
end
end