agent
This commit is contained in:
158
services/tools/channels_test.go
Normal file
158
services/tools/channels_test.go
Normal file
@@ -0,0 +1,158 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"nearle/models"
|
||||
)
|
||||
|
||||
var channelNow = time.Date(2026, 9, 23, 15, 0, 0, 0, time.Local)
|
||||
|
||||
type fakeRevenue struct {
|
||||
summary *models.TenantRevenueSummary
|
||||
err error
|
||||
seenFrom string
|
||||
seenTo string
|
||||
seenLid int
|
||||
seenTid int
|
||||
}
|
||||
|
||||
func (f *fakeRevenue) GetRevenueSummary(tid, lid int, fdate, tdate string) (*models.TenantRevenueSummary, error) {
|
||||
f.seenTid, f.seenLid, f.seenFrom, f.seenTo = tid, lid, fdate, tdate
|
||||
return f.summary, f.err
|
||||
}
|
||||
|
||||
type fakeCounter struct {
|
||||
summary *models.PosSalesSummary
|
||||
err error
|
||||
seen models.PosSalesFilter
|
||||
}
|
||||
|
||||
func (f *fakeCounter) SalesSummary(filter models.PosSalesFilter) (*models.PosSalesSummary, error) {
|
||||
f.seen = filter
|
||||
return f.summary, f.err
|
||||
}
|
||||
|
||||
var atBranch = Caller{Userid: 904, Tenantid: 1147, Locationid: 1172}
|
||||
|
||||
func channelTool(revenue *fakeRevenue, counter *fakeCounter) Tool {
|
||||
return SalesByChannel(revenue, counter, func() time.Time { return channelNow })
|
||||
}
|
||||
|
||||
/* ── The model never sends a date ──────────────────────────────────────── */
|
||||
|
||||
func TestTheDateRangeIsComputedHereNotSentByTheModel(t *testing.T) {
|
||||
// A format, a timezone, or an off-by-one on "last week" each produce a
|
||||
// plausible figure for the wrong period — undetectable in a sentence.
|
||||
revenue, counter := &fakeRevenue{}, &fakeCounter{}
|
||||
if _, err := call1(t, channelTool(revenue, counter), nil, atBranch); err != nil {
|
||||
t.Fatalf("calling: %v", err)
|
||||
}
|
||||
|
||||
// Seven days ending today, inclusive.
|
||||
if revenue.seenFrom != "2026-09-17" || revenue.seenTo != "2026-09-23" {
|
||||
t.Fatalf("range was %s to %s", revenue.seenFrom, revenue.seenTo)
|
||||
}
|
||||
if counter.seen.Fromdate != revenue.seenFrom || counter.seen.Todate != revenue.seenTo {
|
||||
t.Fatalf("the two ledgers were read over different periods: %+v", counter.seen)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTheToolHasNoDateArgumentAtAll(t *testing.T) {
|
||||
tool := SalesByChannel(&fakeRevenue{}, &fakeCounter{}, nil)
|
||||
for _, field := range tool.Schema.Fields {
|
||||
if strings.Contains(field.Name, "date") || strings.Contains(field.Name, "from") {
|
||||
t.Fatalf("the schema offers %q for the model to fill in", field.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestThePeriodCanBeWidened(t *testing.T) {
|
||||
revenue := &fakeRevenue{}
|
||||
if _, err := call1(t, channelTool(revenue, &fakeCounter{}), map[string]any{"days": 30}, atBranch); err != nil {
|
||||
t.Fatalf("calling: %v", err)
|
||||
}
|
||||
if revenue.seenFrom != "2026-08-25" {
|
||||
t.Fatalf("thirty days back was %s", revenue.seenFrom)
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Two ledgers, never one total ──────────────────────────────────────── */
|
||||
|
||||
func TestBothChannelsComeBackSeparately(t *testing.T) {
|
||||
revenue := &fakeRevenue{summary: &models.TenantRevenueSummary{OverallRevenue: 41250}}
|
||||
counter := &fakeCounter{summary: &models.PosSalesSummary{Grosssales: 18300, Billcount: 92}}
|
||||
|
||||
result, err := call1(t, channelTool(revenue, counter), nil, atBranch)
|
||||
if err != nil {
|
||||
t.Fatalf("calling: %v", err)
|
||||
}
|
||||
|
||||
rows, ok := result.Rows.([]ChannelTotals)
|
||||
if !ok || len(rows) != 2 {
|
||||
t.Fatalf("expected two channels: %+v", result.Rows)
|
||||
}
|
||||
if rows[0].Revenue != 41250 || rows[1].Revenue != 18300 {
|
||||
t.Fatalf("the figures did not survive: %+v", rows)
|
||||
}
|
||||
if rows[0].Ledger == rows[1].Ledger {
|
||||
t.Fatal("both channels claim the same ledger")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTheAnswerForbidsAddingTheTwoTogether(t *testing.T) {
|
||||
// The most useful-looking wrong number available on this page.
|
||||
revenue := &fakeRevenue{summary: &models.TenantRevenueSummary{OverallRevenue: 100}}
|
||||
counter := &fakeCounter{summary: &models.PosSalesSummary{Grosssales: 50}}
|
||||
|
||||
result, _ := call1(t, channelTool(revenue, counter), nil, atBranch)
|
||||
if !strings.Contains(strings.ToLower(result.Note), "do not add") {
|
||||
t.Fatalf("nothing stops the model reporting one total: %q", result.Note)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTheCounterFigureSaysItIsGross(t *testing.T) {
|
||||
counter := &fakeCounter{summary: &models.PosSalesSummary{Grosssales: 50, Billcount: 3}}
|
||||
result, _ := call1(t, channelTool(&fakeRevenue{}, counter), nil, atBranch)
|
||||
|
||||
rows := result.Rows.([]ChannelTotals)
|
||||
if rows[len(rows)-1].Caveat == "" {
|
||||
t.Fatal("a gross figure is presented as comparable without saying so")
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Scope ─────────────────────────────────────────────────────────────── */
|
||||
|
||||
func TestChannelsRefuseAnAllBranchesQuestion(t *testing.T) {
|
||||
// The counter side is readable one outlet at a time. Answering with the app
|
||||
// half alone would be presented as the whole comparison.
|
||||
_, err := call1(t, channelTool(&fakeRevenue{}, &fakeCounter{}), nil, merchantCaller)
|
||||
if err == nil {
|
||||
t.Fatal("an all-branches comparison was answered")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTheBranchComesFromTheSession(t *testing.T) {
|
||||
revenue := &fakeRevenue{}
|
||||
if _, err := call1(t, channelTool(revenue, &fakeCounter{}), nil, atBranch); err != nil {
|
||||
t.Fatalf("calling: %v", err)
|
||||
}
|
||||
if revenue.seenLid != 1172 {
|
||||
t.Fatalf("read branch %d", revenue.seenLid)
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Failure ───────────────────────────────────────────────────────────── */
|
||||
|
||||
func TestAHalfAnsweredComparisonIsAnErrorNotHalfAnAnswer(t *testing.T) {
|
||||
// One channel returned alone would be read as "the counter took nothing".
|
||||
revenue := &fakeRevenue{summary: &models.TenantRevenueSummary{OverallRevenue: 100}}
|
||||
counter := &fakeCounter{err: errors.New("pos database is down")}
|
||||
|
||||
if _, err := call1(t, channelTool(revenue, counter), nil, atBranch); err == nil {
|
||||
t.Fatal("a failed counter read produced a one-sided comparison")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user