package store import ( "context" "errors" "testing" "time" "git.avsdev.uk/Go/job-search/internal/types" ) // A batch recorded after the clock went back is still created after the // newest batch, so asking for the batches after that one finds it. func TestChangeBatchAfterClockWentBack(t *testing.T) { db := openTestDB(t) s := &Store{db: db} ctx := context.Background() _, err := s.SaveOpportunity( ctx, &types.Opportunity{ UUID: "ocds-1", LatestReleaseDate: time.Now(), }, ) if err != nil { t.Fatal(err) } future := time.Now().UTC().Add(time.Hour) db.MustExec(insertChangeBatch, "future", future) err = s.SetMarks(ctx, types.OpportunityMarks{ UUID: "ocds-1", Won: true, }) if err != nil { t.Fatal(err) } var latest changeBatch if err := db.Get(&latest, selectLatestChangeBatch); err != nil { t.Fatal(err) } if !latest.CreatedAt.After(future) { t.Errorf("batch created at %v, not after %v", latest.CreatedAt, future) } got, hash, err := s.ListChangedOpportunities(ctx, "future", time.Time{}) if err != nil { t.Fatal(err) } if len(got) != 1 || got[0].UUID != "ocds-1" || hash != latest.Hash { t.Errorf("changed after future: %v, %q", got, hash) } } // Recording a batch deletes the batches older than the retention, with their // records of opportunities; with no retention, none are deleted. func TestChangeBatchRetention(t *testing.T) { for _, retention := range []time.Duration{time.Hour, 0} { db := openTestDB(t) s := &Store{ db: db, changeBatchRetention: retention, } ctx := context.Background() _, err := s.SaveOpportunity( ctx, &types.Opportunity{ UUID: "ocds-1", LatestReleaseDate: time.Now(), }, ) if err != nil { t.Fatal(err) } // Backdate every batch so far by two hours. db.MustExec( `UPDATE opportunity_change_batches SET created_at = ?`, time.Now().UTC().Add(-2*time.Hour), ) old, err := s.LatestChangeBatch(ctx) if err != nil { t.Fatal(err) } err = s.SetMarks(ctx, types.OpportunityMarks{ UUID: "ocds-1", Skipped: true, }) if err != nil { t.Fatal(err) } var batches, records int db.Get(&batches, `SELECT COUNT(*) FROM opportunity_change_batches`) db.Get( &records, `SELECT COUNT(*) FROM opportunity_change_batch_opportunities`, ) _, _, err = s.ListChangedOpportunities(ctx, old, time.Time{}) if retention > 0 { if batches != 1 || records != 1 || !errors.Is(err, ErrUnknownBatch) { t.Errorf( "retention %v: %d batches, %d records, err %v; "+ "want the old batch gone", retention, batches, records, err, ) } continue } if batches != 2 || records != 2 || err != nil { t.Errorf( "no retention: %d batches, %d records, err %v; want both kept", batches, records, err, ) } } }