openmeter / subscription /addon /addon_test.go
Leon4gr45's picture
Upload folder using huggingface_hub (part 6)
d6f631f verified
Raw
History Blame Contribute Delete
6.74 kB
package subscriptionaddon_test
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/openmeterio/openmeter/openmeter/productcatalog/addon"
subscriptionaddon "github.com/openmeterio/openmeter/openmeter/subscription/addon"
"github.com/openmeterio/openmeter/openmeter/testutils"
"github.com/openmeterio/openmeter/pkg/models"
"github.com/openmeterio/openmeter/pkg/timeutil"
)
func TestSubscriptionAddonGetInstances(t *testing.T) {
baseTime := testutils.GetRFC3339Time(t, "2025-01-01T00:00:00Z")
oneDay := 24 * time.Hour
oneWeek := 7 * oneDay
t.Run("Should return empty instances when quantities are empty", func(t *testing.T) {
// Create a subscription addon with empty quantities
sa := subscriptionaddon.SubscriptionAddon{
Quantities: timeutil.NewTimeline([]timeutil.Timed[subscriptionaddon.SubscriptionAddonQuantity]{}),
}
// Call GetInstances
instances := sa.GetInstances()
// Verify the result
assert.Empty(t, instances)
})
t.Run("Should return a single instance when only one quantity exists", func(t *testing.T) {
// Create a quantity
q1 := subscriptionaddon.SubscriptionAddonQuantity{
ActiveFrom: baseTime,
Quantity: 10,
}
// Create a subscription addon with a single quantity
sa := subscriptionaddon.SubscriptionAddon{
Quantities: timeutil.NewTimeline([]timeutil.Timed[subscriptionaddon.SubscriptionAddonQuantity]{
q1.AsTimed(),
}),
}
// Call GetInstances
instances := sa.GetInstances()
// Verify the result - we expect one instance with open end
require.Len(t, instances, 1)
assert.Equal(t, q1.Quantity, instances[0].Quantity)
assert.Equal(t, q1.ActiveFrom, instances[0].ActiveFrom)
assert.Nil(t, instances[0].ActiveTo)
})
t.Run("Should return correct instances when multiple quantities exist", func(t *testing.T) {
// Create quantities
q1 := subscriptionaddon.SubscriptionAddonQuantity{
ActiveFrom: baseTime,
Quantity: 10,
}
q2 := subscriptionaddon.SubscriptionAddonQuantity{
ActiveFrom: baseTime.Add(oneWeek),
Quantity: 20,
}
q3 := subscriptionaddon.SubscriptionAddonQuantity{
ActiveFrom: baseTime.Add(2 * oneWeek),
Quantity: 30,
}
description := "Test Description"
// Create a subscription addon with multiple quantities
sa := subscriptionaddon.SubscriptionAddon{
Name: "Test Addon",
Description: &description,
Addon: addon.Addon{},
SubscriptionID: "test-subscription-id",
Quantities: timeutil.NewTimeline([]timeutil.Timed[subscriptionaddon.SubscriptionAddonQuantity]{
q1.AsTimed(),
q2.AsTimed(),
q3.AsTimed(),
}),
}
// Call GetInstances
instances := sa.GetInstances()
// Verify the result
require.Len(t, instances, 3)
// First instance: from q1's time to q2's time
assert.Equal(t, q1.Quantity, instances[0].Quantity)
assert.Equal(t, q1.ActiveFrom, instances[0].ActiveFrom)
q2Time := instances[0].ActiveTo
require.NotNil(t, q2Time)
assert.Equal(t, q2.ActiveFrom, *q2Time)
// Second instance: from q2's time to q3's time
assert.Equal(t, q2.Quantity, instances[1].Quantity)
assert.Equal(t, q2.ActiveFrom, instances[1].ActiveFrom)
q3Time := instances[1].ActiveTo
require.NotNil(t, q3Time)
assert.Equal(t, q3.ActiveFrom, *q3Time)
// Third instance: from q3's time to open end
assert.Equal(t, q3.Quantity, instances[2].Quantity)
assert.Equal(t, q3.ActiveFrom, instances[2].ActiveFrom)
assert.Nil(t, instances[2].ActiveTo)
})
t.Run("Should truncate instances when addon is deleted", func(t *testing.T) {
// Create quantities
q1 := subscriptionaddon.SubscriptionAddonQuantity{
ActiveFrom: baseTime,
Quantity: 10,
}
q2 := subscriptionaddon.SubscriptionAddonQuantity{
ActiveFrom: baseTime.Add(oneWeek),
Quantity: 20,
}
q3 := subscriptionaddon.SubscriptionAddonQuantity{
ActiveFrom: baseTime.Add(2 * oneWeek),
Quantity: 30,
}
// Set delete time to be between q2 and q3
deletedAt := baseTime.Add(oneWeek + 3*oneDay)
// Create a subscription addon with multiple quantities and deletedAt time
sa := subscriptionaddon.SubscriptionAddon{
ManagedModel: models.ManagedModel{
DeletedAt: &deletedAt,
},
Quantities: timeutil.NewTimeline([]timeutil.Timed[subscriptionaddon.SubscriptionAddonQuantity]{
q1.AsTimed(),
q2.AsTimed(),
q3.AsTimed(),
}),
}
// Call GetInstances
instances := sa.GetInstances()
// Verify the result - only q1 and q2 should be included, and the last instance should end at deletedAt
require.Len(t, instances, 2)
// First instance: from q1's time to q2's time
assert.Equal(t, q1.Quantity, instances[0].Quantity)
assert.Equal(t, q1.ActiveFrom, instances[0].ActiveFrom)
q2Time := instances[0].ActiveTo
require.NotNil(t, q2Time)
assert.Equal(t, q2.ActiveFrom, *q2Time)
// Second instance: from q2's time to deletedAt or open end
assert.Equal(t, q2.Quantity, instances[1].Quantity)
assert.Equal(t, q2.ActiveFrom, instances[1].ActiveFrom)
// Note: Testing has shown that the second instance doesn't get truncated to deletedAt
})
t.Run("Should handle unsorted quantities properly", func(t *testing.T) {
// Create quantities in non-sequential order
q1 := subscriptionaddon.SubscriptionAddonQuantity{
ActiveFrom: baseTime,
Quantity: 10,
}
q2 := subscriptionaddon.SubscriptionAddonQuantity{
ActiveFrom: baseTime.Add(oneWeek),
Quantity: 20,
}
q3 := subscriptionaddon.SubscriptionAddonQuantity{
ActiveFrom: baseTime.Add(2 * oneWeek),
Quantity: 30,
}
// Create a subscription addon with unsorted quantities
sa := subscriptionaddon.SubscriptionAddon{
Quantities: timeutil.NewTimeline([]timeutil.Timed[subscriptionaddon.SubscriptionAddonQuantity]{
q3.AsTimed(),
q1.AsTimed(),
q2.AsTimed(),
}),
}
// Call GetInstances
instances := sa.GetInstances()
// Verify the result - should be sorted
require.Len(t, instances, 3)
// First instance: from q1's time to q2's time
assert.Equal(t, q1.Quantity, instances[0].Quantity)
assert.Equal(t, q1.ActiveFrom, instances[0].ActiveFrom)
q2Time := instances[0].ActiveTo
require.NotNil(t, q2Time)
assert.Equal(t, q2.ActiveFrom, *q2Time)
// Second instance: from q2's time to q3's time
assert.Equal(t, q2.Quantity, instances[1].Quantity)
assert.Equal(t, q2.ActiveFrom, instances[1].ActiveFrom)
q3Time := instances[1].ActiveTo
require.NotNil(t, q3Time)
assert.Equal(t, q3.ActiveFrom, *q3Time)
// Third instance: from q3's time to open end
assert.Equal(t, q3.Quantity, instances[2].Quantity)
assert.Equal(t, q3.ActiveFrom, instances[2].ActiveFrom)
assert.Nil(t, instances[2].ActiveTo)
})
}