package confirmemailcode import ( "context" "testing" "time" "galaxy/authsession/internal/domain/challenge" authtelemetry "galaxy/authsession/internal/telemetry" "galaxy/authsession/internal/testkit" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/attribute" sdkmetric "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/metric/metricdata" ) func TestExecuteRecordsInvalidCodeMetricForThrottledChallenge(t *testing.T) { t.Parallel() runtime, reader := newObservedConfirmTelemetryRuntime(t) deps := newConfirmDeps(t) record := sentChallengeFixture(t, deps.hasher, "challenge-1", "pilot@example.com", "654321", deps.now.Add(-time.Minute), deps.now.Add(time.Minute)) record.Status = challenge.StatusDeliveryThrottled record.DeliveryState = challenge.DeliveryThrottled require.NoError(t, record.Validate()) require.NoError(t, deps.challengeStore.Create(context.Background(), record)) service, err := NewWithTelemetry( deps.challengeStore, deps.sessionStore, deps.userDirectory, deps.configProvider, deps.publisher, deps.idGenerator, deps.hasher, testkit.FixedClock{Time: deps.now}, runtime, ) require.NoError(t, err) _, err = service.Execute(context.Background(), Input{ ChallengeID: "challenge-1", Code: "654321", ClientPublicKey: publicKeyString(), TimeZone: confirmEmailCodeTimeZone, }) require.Error(t, err) assertConfirmMetricCount(t, reader, map[string]string{"outcome": "invalid_code"}, 1) } func newObservedConfirmTelemetryRuntime(t *testing.T) (*authtelemetry.Runtime, *sdkmetric.ManualReader) { t.Helper() reader := sdkmetric.NewManualReader() provider := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)) runtime, err := authtelemetry.New(provider) require.NoError(t, err) return runtime, reader } func assertConfirmMetricCount(t *testing.T, reader *sdkmetric.ManualReader, wantAttrs map[string]string, wantValue int64) { t.Helper() var resourceMetrics metricdata.ResourceMetrics require.NoError(t, reader.Collect(context.Background(), &resourceMetrics)) for _, scopeMetrics := range resourceMetrics.ScopeMetrics { for _, metric := range scopeMetrics.Metrics { if metric.Name != "authsession.confirm_email_code.attempts" { continue } sum, ok := metric.Data.(metricdata.Sum[int64]) require.True(t, ok) for _, point := range sum.DataPoints { if hasConfirmMetricAttributes(point.Attributes.ToSlice(), wantAttrs) { assert.Equal(t, wantValue, point.Value) return } } } } require.Failf(t, "test failed", "confirm metric with attrs %v not found", wantAttrs) } func hasConfirmMetricAttributes(values []attribute.KeyValue, want map[string]string) bool { if len(values) != len(want) { return false } for _, value := range values { if want[string(value.Key)] != value.Value.AsString() { return false } } return true }