001/*
002 * Copyright 2020 Global Biodiversity Information Facility (GBIF)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.gbif.api.model.checklistbank;
017
018import org.gbif.api.util.IsoDateParsingUtils;
019import org.gbif.api.vocabulary.Extension;
020import org.gbif.dwc.terms.DcTerm;
021import org.gbif.dwc.terms.DwcTerm;
022import org.gbif.dwc.terms.GbifTerm;
023import org.gbif.dwc.terms.IucnTerm;
024import org.gbif.dwc.terms.Term;
025import org.gbif.dwc.terms.TermFactory;
026import org.gbif.dwc.terms.UnknownTerm;
027
028import java.io.IOException;
029import java.util.ArrayList;
030import java.util.Date;
031import java.util.HashMap;
032import java.util.List;
033import java.util.Map;
034
035import org.apache.commons.text.RandomStringGenerator;
036import org.junit.jupiter.api.Test;
037
038import com.fasterxml.jackson.annotation.JsonInclude;
039import com.fasterxml.jackson.databind.DeserializationFeature;
040import com.fasterxml.jackson.databind.ObjectMapper;
041import com.fasterxml.jackson.databind.SerializationFeature;
042
043import static org.junit.jupiter.api.Assertions.assertEquals;
044import static org.junit.jupiter.api.Assertions.assertFalse;
045import static org.junit.jupiter.api.Assertions.assertNotEquals;
046import static org.junit.jupiter.api.Assertions.assertNotNull;
047import static org.junit.jupiter.api.Assertions.assertTrue;
048
049public class VerbatimNameUsageTest {
050
051  @Test
052  public void testHasExtension() {
053    VerbatimNameUsage v1 = new VerbatimNameUsage();
054    v1.setCoreField(DwcTerm.taxonID, "IPNI342");
055    v1.setCoreField(DwcTerm.scientificName, "Abies alba");
056    v1.setCoreField(DwcTerm.scientificNameAuthorship, "Miller");
057    v1.setCoreField(DwcTerm.taxonRank, "species");
058    assertFalse(v1.hasExtension(Extension.IDENTIFICATION));
059
060    List<Map<Term, String>> exts = new ArrayList<>();
061    v1.getExtensions().put(Extension.IDENTIFICATION, exts);
062    assertFalse(v1.hasExtension(Extension.IDENTIFICATION));
063    assertFalse(v1.hasExtension(DwcTerm.Identification));
064
065    exts.add(new HashMap<>());
066    assertTrue(v1.hasExtension(Extension.IDENTIFICATION));
067    assertTrue(v1.hasExtension(DwcTerm.Identification));
068    assertFalse(v1.hasExtension(DwcTerm.MeasurementOrFact));
069  }
070
071  @Test
072  public void testEquality() {
073    VerbatimNameUsage v1 = new VerbatimNameUsage();
074    v1.setCoreField(DwcTerm.taxonID, "IPNI342");
075    v1.setCoreField(DwcTerm.scientificName, "Abies alba");
076    v1.setCoreField(DwcTerm.scientificNameAuthorship, "Miller");
077    v1.setCoreField(DwcTerm.taxonRank, "species");
078
079    VerbatimNameUsage v2 = new VerbatimNameUsage();
080    v2.setCoreField(DwcTerm.taxonID, "IPNI342");
081    v2.setCoreField(DwcTerm.scientificName, "Abies alba");
082    v2.setCoreField(DwcTerm.scientificNameAuthorship, "Miller");
083    v2.setCoreField(DwcTerm.taxonRank, "species");
084
085    assertEquals(v1, v2);
086
087    v1.setLastCrawled(new Date());
088    assertNotEquals(v2, v1);
089  }
090
091  @Test
092  public void testFieldUpdate() {
093    VerbatimNameUsage occ = new VerbatimNameUsage();
094    String catNum = "abc123";
095    occ.setCoreField(DwcTerm.catalogNumber, catNum);
096    assertEquals(catNum, occ.getCoreField(DwcTerm.catalogNumber));
097
098    String catNum2 = "qwer";
099    occ.setCoreField(DwcTerm.catalogNumber, catNum2);
100    assertEquals(catNum2, occ.getCoreField(DwcTerm.catalogNumber));
101  }
102
103  @Test
104  public void testHasField() {
105    VerbatimNameUsage occ = new VerbatimNameUsage();
106
107    occ.setCoreField(DwcTerm.catalogNumber, "abc123");
108    assertTrue(occ.hasCoreField(DwcTerm.catalogNumber));
109    assertFalse(occ.hasCoreField(DwcTerm.institutionCode));
110
111    occ.setCoreField(DwcTerm.catalogNumber, " ");
112    assertTrue(occ.hasCoreField(DwcTerm.catalogNumber));
113
114    occ.setCoreField(DwcTerm.catalogNumber, "");
115    assertFalse(occ.hasCoreField(DwcTerm.catalogNumber));
116
117    occ.setCoreField(DwcTerm.catalogNumber, null);
118    assertFalse(occ.hasCoreField(DwcTerm.catalogNumber));
119  }
120
121  @Test
122  public void testFieldFromTermFactory() {
123    VerbatimNameUsage occ = new VerbatimNameUsage();
124    String prefix = "t_";
125    String colName = "t_dwc:basisOfRecord";
126    Term term = TermFactory.instance().findTerm(colName.substring(prefix.length()));
127    occ.setCoreField(term, "PreservedSpecimen");
128    assertEquals(1, occ.getFields().size());
129    assertTrue(occ.hasCoreField(DwcTerm.basisOfRecord));
130    assertEquals("PreservedSpecimen", occ.getCoreField(DwcTerm.basisOfRecord));
131  }
132
133  @Test
134  public void testJsonSerde() throws IOException {
135    ObjectMapper mapper = new ObjectMapper();
136
137    VerbatimNameUsage verb = new VerbatimNameUsage();
138    verb.setCoreField(DwcTerm.institutionCode, "IC");
139    verb.setCoreField(DwcTerm.collectionCode, "BUGS");
140    verb.setCoreField(DwcTerm.catalogNumber, "MD10782");
141
142    String json = mapper.writeValueAsString(verb);
143    VerbatimNameUsage deser = mapper.readValue(json, VerbatimNameUsage.class);
144    assertEquals(verb, deser);
145    for (DwcTerm term : DwcTerm.values()) {
146      assertEquals(verb.getCoreField(term), deser.getCoreField(term));
147    }
148  }
149
150  @Test
151  public void testJsonSerdeAllFields() throws IOException {
152    ObjectMapper mapper = new ObjectMapper();
153
154    VerbatimNameUsage verb = new VerbatimNameUsage();
155    verb.setKey(123);
156    String termPrefix = "I am Jack's ";
157    for (Term term : DwcTerm.values()) {
158      verb.setCoreField(term, termPrefix + term);
159    }
160    for (Term term : DcTerm.values()) {
161      verb.setCoreField(term, termPrefix + term);
162    }
163    for (Term term : GbifTerm.values()) {
164      verb.setCoreField(term, termPrefix + term);
165    }
166    for (Term term : IucnTerm.values()) {
167      verb.setCoreField(term, termPrefix + term);
168    }
169
170    String json = mapper.writeValueAsString(verb);
171    VerbatimNameUsage deser = mapper.readValue(json, VerbatimNameUsage.class);
172    assertEquals(verb, deser);
173    for (Term term : DwcTerm.values()) {
174      assertTrue(deser.hasCoreField(term));
175      assertEquals(termPrefix + term, deser.getCoreField(term));
176    }
177    for (Term term : DcTerm.values()) {
178      assertTrue(deser.hasCoreField(term));
179      assertEquals(termPrefix + term, deser.getCoreField(term));
180    }
181    for (Term term : GbifTerm.values()) {
182      assertTrue(deser.hasCoreField(term));
183      assertEquals(termPrefix + term, deser.getCoreField(term));
184    }
185    for (Term term : IucnTerm.values()) {
186      assertTrue(deser.hasCoreField(term));
187      assertEquals(termPrefix + term, deser.getCoreField(term));
188    }
189  }
190
191  @Test
192  public void testVerbatimMapSerde() throws Exception {
193    ObjectMapper mapper = new ObjectMapper();
194    mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
195    mapper.enable(SerializationFeature.INDENT_OUTPUT);
196    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
197
198    VerbatimNameUsage v = new VerbatimNameUsage();
199    v.setKey(7);
200    v.setLastCrawled(new Date());
201
202    char [][] alphabeticPairs = {{'a','z'},{'A','Z'}};
203    char [][] alphanumericPairs = {{'a','z'},{'A','Z'},{'0','9'}};
204    RandomStringGenerator generatorAlphabetic = new RandomStringGenerator.Builder()
205        .withinRange(alphabeticPairs)
206        .build();
207    RandomStringGenerator generatorAlphanumeric = new RandomStringGenerator.Builder()
208        .withinRange(alphanumericPairs)
209        .build();
210
211    for (Term term : DwcTerm.values()) {
212      v.setCoreField(term, generatorAlphabetic.generate(20));
213    }
214    final int numDwcTerms = v.getFields().size();
215
216    for (Term term : DcTerm.values()) {
217      v.setCoreField(term, generatorAlphabetic.generate(20));
218    }
219    final int numDcTerms = v.getFields().size() - numDwcTerms;
220
221    for (Term term : GbifTerm.values()) {
222      v.setCoreField(term, generatorAlphabetic.generate(20));
223    }
224    final int numGbifTerms = v.getFields().size() - numDwcTerms - numDcTerms;
225
226    for (Term term : IucnTerm.values()) {
227      v.setCoreField(term, generatorAlphanumeric.generate(20));
228    }
229    final int numIucnTerms = v.getFields().size() - numDwcTerms - numDcTerms - numGbifTerms;
230
231    v.setCoreField(DwcTerm.scientificName, "Abies alba");
232    v.setCoreField(DwcTerm.collectionCode, "BUGS");
233    v.setCoreField(DwcTerm.catalogNumber, "MD10782");
234    v.setCoreField(UnknownTerm.build("http://rs.un.org/terms/temperatur"), generatorAlphabetic.generate(30));
235    v.setCoreField(UnknownTerm.build("http://rs.un.org/terms/co2"), generatorAlphabetic.generate(30));
236    v.setCoreField(UnknownTerm.build("http://rs.un.org/terms/modified"), new Date().toString());
237    v.setCoreField(UnknownTerm.build("http://rs.un.org/terms/scientificName"), generatorAlphabetic.generate(30));
238    final int numOtherTerms = v.getFields().size() - numDwcTerms - numDcTerms - numGbifTerms - numIucnTerms;
239
240    final int numTerms = v.getFields().size();
241
242    assertEquals(numTerms, numDwcTerms + numDcTerms + numGbifTerms + numIucnTerms + numOtherTerms);
243
244    String json = mapper.writeValueAsString(v);
245    System.out.println(json);
246
247    VerbatimNameUsage v2 = mapper.readValue(json, VerbatimNameUsage.class);
248    // 5 terms
249    assertEquals(numTerms, v2.getFields().size());
250  }
251
252  @Test
253  public void testVerbatimExtensionsMapSerde() throws Exception {
254    ObjectMapper mapper = new ObjectMapper();
255    mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
256    mapper.enable(SerializationFeature.INDENT_OUTPUT);
257    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
258
259    Map<Term, String> verbatimRecord = new HashMap<>();
260    verbatimRecord.put(DcTerm.created, "2021-10-25");
261    verbatimRecord.put(DcTerm.creator, "fede");
262    verbatimRecord.put(DcTerm.description, "testDescription");
263    verbatimRecord.put(DcTerm.format, "jpg");
264    verbatimRecord.put(DcTerm.license, "licenseTest");
265    verbatimRecord.put(DcTerm.publisher, "publisherTest");
266    verbatimRecord.put(DcTerm.title, "titleTest");
267    verbatimRecord.put(DcTerm.references, "http://www.gbif.org/");
268    verbatimRecord.put(DcTerm.identifier, "http://www.gbif.org/");
269
270    VerbatimNameUsage v = new VerbatimNameUsage();
271    v.setKey(7);
272    v.setLastCrawled(new Date());
273    Map<Extension, List<Map<Term, String>>> extensions = new HashMap<>();
274    List<Map<Term, String>> verbatimRecords = new ArrayList<>();
275    verbatimRecords.add(verbatimRecord);
276    extensions.put(Extension.MULTIMEDIA, verbatimRecords);
277    v.setExtensions(extensions);
278
279    String json = mapper.writeValueAsString(v);
280    System.out.println(json);
281
282    VerbatimNameUsage v2 = mapper.readValue(json, VerbatimNameUsage.class);
283    assertNotNull(v2.getExtensions());
284    assertFalse(v2.getExtensions().get(Extension.MULTIMEDIA).isEmpty());
285    assertEquals(v2.getExtensions().get(Extension.MULTIMEDIA).get(0), verbatimRecord);
286  }
287}