tane/apps/app_seeds/test/domain/species_reference_links_test.dart
vjrj fde0ea6eab feat(species): derived verified reference links (GBIF/Wikipedia/Wikispecies)
Add a read-only "Learn more" section on the variety detail that surfaces
verified external references for the linked species, built deterministically
from bundled identifiers — no titles bundled, no network, offline-first:

- GBIF taxon page from the backbone key
- Wikipedia via Wikidata Special:GoToLinkedPage (locale-aware, RTL-safe,
  falls back to the Wikidata item when a language lacks the article)
- Wikispecies from the scientific name

Enrich the bundled catalog (species.json v3) with gbif_key + wikidata_qid for
all 14 species, cross-checked (each QID carries GBIF ID P846 = the key).
Schema already had the columns; seedBundled now persists and backfills them.

The grower's own manual links stay but are demoted (progressive disclosure):
the section only shows when links exist and "Add link" is a low-emphasis
button, since hand-adding a link is the rarer power move.

Pure-Dart link builder is unit-tested; repo persistence/backfill and the
detail-screen section are covered too.
2026-07-09 22:44:12 +02:00

84 lines
2.7 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter_test/flutter_test.dart';
import 'package:tane/domain/species_reference_links.dart';
void main() {
test('all identifiers present yields gbif, wikipedia and wikispecies', () {
final links = speciesReferenceLinks(
scientificName: 'Solanum lycopersicum',
gbifKey: 2930137,
wikidataQid: 'Q23501',
languageCode: 'es',
);
expect(links.map((l) => l.source), [
ReferenceSource.gbif,
ReferenceSource.wikipedia,
ReferenceSource.wikispecies,
]);
expect(links[0].url, 'https://www.gbif.org/species/2930137');
expect(
links[1].url,
'https://www.wikidata.org/wiki/Special:GoToLinkedPage/eswiki/Q23501',
);
expect(
links[2].url,
'https://species.wikimedia.org/wiki/Solanum_lycopersicum',
);
});
test('wikipedia link is locale-aware', () {
String wiki(String lang) => speciesReferenceLinks(
scientificName: 'Zea mays',
wikidataQid: 'Q11575',
languageCode: lang,
).firstWhere((l) => l.source == ReferenceSource.wikipedia).url;
expect(wiki('en'), contains('/enwiki/Q11575'));
expect(wiki('ar'), contains('/arwiki/Q11575'));
});
test('locale region and case are normalised to the bare wiki subtag', () {
String wiki(String lang) => speciesReferenceLinks(
scientificName: 'Zea mays',
wikidataQid: 'Q11575',
languageCode: lang,
).firstWhere((l) => l.source == ReferenceSource.wikipedia).url;
expect(wiki('pt_BR'), contains('/ptwiki/'));
expect(wiki('zh-Hans'), contains('/zhwiki/'));
expect(wiki('EN'), contains('/enwiki/'));
expect(wiki(''), contains('/enwiki/')); // empty locale → English
});
test('a missing identifier simply drops that source', () {
final onlyGbif = speciesReferenceLinks(
scientificName: '', // no wikispecies without a name
gbifKey: 42,
);
expect(onlyGbif.map((l) => l.source), [ReferenceSource.gbif]);
final blankQid = speciesReferenceLinks(
scientificName: 'Daucus carota',
wikidataQid: ' ',
);
expect(
blankQid.map((l) => l.source),
isNot(contains(ReferenceSource.wikipedia)),
);
expect(blankQid.map((l) => l.source), [ReferenceSource.wikispecies]);
});
test('nothing identifiable yields no links', () {
expect(speciesReferenceLinks(scientificName: ' '), isEmpty);
});
test('scientific names with spaces and diacritics are URL-safe', () {
final link = speciesReferenceLinks(
scientificName: 'Allium × proliferum',
).single;
expect(link.source, ReferenceSource.wikispecies);
expect(
link.url,
'https://species.wikimedia.org/wiki/Allium_%C3%97_proliferum',
);
});
}