import 'package:commons_core/commons_core.dart'; import 'package:drift/drift.dart' show Value; import 'package:flutter_test/flutter_test.dart'; import 'package:tane/data/species_catalog.dart'; import 'package:tane/data/species_repository.dart'; import 'package:tane/db/database.dart'; import '../support/test_support.dart'; const _seeds = [ SpeciesSeed( scientificName: 'Solanum lycopersicum', family: 'Solanaceae', commonNames: { 'en': ['Tomato'], 'es': ['Tomate'], }, ), SpeciesSeed( scientificName: 'Phaseolus vulgaris', family: 'Fabaceae', commonNames: { 'en': ['Common bean'], 'es': ['Judía', 'Alubia'], }, ), ]; void main() { late AppDatabase db; late SpeciesRepository repo; setUp(() { db = newTestDatabase(); repo = SpeciesRepository(db, idGen: IdGen()); }); tearDown(() => db.close()); test( 'parseSpeciesCatalog reads scientific name, family and common names', () { const json = ''' {"version":1,"species":[ {"scientific_name":"Zea mays","family":"Poaceae","common":{"en":["Maize"],"es":["Maíz"]}} ]}'''; final seeds = parseSpeciesCatalog(json); expect(seeds.single.scientificName, 'Zea mays'); expect(seeds.single.family, 'Poaceae'); expect(seeds.single.commonNames['es'], ['Maíz']); }, ); test('parseSpeciesCatalog reads gbif and wikidata identifiers', () { const json = ''' {"version":3,"species":[ {"scientific_name":"Zea mays","gbif_key":5290052,"wikidata_qid":"Q11575"}, {"scientific_name":"Unknown sp."} ]}'''; final seeds = parseSpeciesCatalog(json); expect(seeds.first.gbifKey, 5290052); expect(seeds.first.wikidataQid, 'Q11575'); // Missing identifiers stay null, they are optional. expect(seeds.last.gbifKey, isNull); expect(seeds.last.wikidataQid, isNull); }); test('seedBundled persists gbif and wikidata identifiers', () async { await repo.seedBundled(const [ SpeciesSeed( scientificName: 'Zea mays', gbifKey: 5290052, wikidataQid: 'Q11575', ), ]); final row = await db.select(db.species).getSingle(); expect(row.gbifKey, 5290052); expect(row.wikidataQid, 'Q11575'); }); test( 'seedBundled backfills identifiers onto rows seeded before them', () async { // A pre-existing bundled row that predates the identifier fields. await db .into(db.species) .insert( SpeciesCompanion.insert( id: 'legacy', createdAt: 0, updatedAt: '0', lastAuthor: 'bundle', scientificName: 'Zea mays', isBundled: const Value(true), ), ); await repo.seedBundled(const [ SpeciesSeed( scientificName: 'Zea mays', gbifKey: 5290052, wikidataQid: 'Q11575', ), ]); final rows = await db.select(db.species).get(); expect(rows.single.id, 'legacy'); // same row, not a duplicate expect(rows.single.gbifKey, 5290052); expect(rows.single.wikidataQid, 'Q11575'); }, ); test('seedBundled inserts species and is idempotent', () async { await repo.seedBundled(_seeds); await repo.seedBundled(_seeds); // second run must not duplicate final species = await db.select(db.species).get(); expect(species.length, 2); expect(species.every((s) => s.isBundled), isTrue); }); test('search matches by scientific name', () async { await repo.seedBundled(_seeds); final results = await repo.search('phaseolus'); expect(results.single.scientificName, 'Phaseolus vulgaris'); }); test('search matches by common name and returns a localized label', () async { await repo.seedBundled(_seeds); final es = await repo.search('alubia', languageCode: 'es'); expect(es.single.scientificName, 'Phaseolus vulgaris'); expect(es.single.commonName, anyOf('Judía', 'Alubia')); final en = await repo.search('tom', languageCode: 'en'); expect(en.single.commonName, 'Tomato'); expect(en.single.displayLabel, 'Tomato (Solanum lycopersicum)'); }); test('empty query returns nothing', () async { await repo.seedBundled(_seeds); expect(await repo.search(' '), isEmpty); }); }