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.common; 017 018import org.gbif.api.SerdeTestUtils; 019 020import java.io.IOException; 021import java.net.URI; 022import java.net.URLEncoder; 023import java.util.Objects; 024 025import org.junit.jupiter.api.Test; 026 027import static org.junit.jupiter.api.Assertions.assertEquals; 028import static org.junit.jupiter.api.Assertions.assertFalse; 029import static org.junit.jupiter.api.Assertions.assertTrue; 030import static org.junit.jupiter.api.Assertions.fail; 031 032public class DOITest { 033 034 @Test 035 public void testPrefixConstructor() { 036 DOI d = new DOI("10.1234", "1ASCDU"); 037 assertEquals(d, new DOI("doi:10.1234/1ASCDU")); 038 } 039 040 @Test 041 public void testIsParsable() { 042 assertFalse(DOI.isParsable(null)); 043 assertFalse(DOI.isParsable("")); 044 assertFalse(DOI.isParsable("10.1234.1ASCDU")); 045 assertFalse(DOI.isParsable("DOI:123")); 046 assertFalse(DOI.isParsable(" ")); 047 048 assertTrue(DOI.isParsable("http://dx.doi.org/urn:doi:10.1234/1ASCDU")); 049 assertTrue(DOI.isParsable("http://doi.org/urn:doi:10.1234/1ASCDU")); 050 assertTrue(DOI.isParsable("http://dx.doi.org/doi:10.1234/1ASCDU")); 051 assertTrue(DOI.isParsable("http://doi.org/doi:10.1234/1ASCDU")); 052 assertTrue(DOI.isParsable("http://dx.doi.org/10.1234/1ASCDU")); 053 assertTrue(DOI.isParsable("http://doi.org/10.1234/1ASCDU")); 054 assertTrue(DOI.isParsable("https://dx.doi.org/10.1234/1ASCDU")); 055 assertTrue(DOI.isParsable("https://doi.org/10.1234/1ASCDU")); 056 057 assertTrue(DOI.isParsable("doi:10.1234/1ASCDU")); 058 assertTrue(DOI.isParsable("urn:doi:10.1234/1ASCDU")); 059 assertTrue(DOI.isParsable("doi:10.1234/1ASCDU")); 060 assertTrue(DOI.isParsable("urn:doi:10.1234/1ASCDU")); 061 assertTrue(DOI.isParsable("doi:10.1234/1ascdu")); 062 assertTrue(DOI.isParsable("urn:doi:10.1234/1ascdu")); 063 assertTrue(DOI.isParsable("10.1234/1ascdu")); 064 assertTrue(DOI.isParsable("10.1234/1ASCDU")); 065 066 // This is real. 067 assertTrue(DOI.isParsable("10.1643/0045-8511(2007)2007[699:Tnvsot]2.0.Co;2")); 068 assertTrue(DOI.isParsable("doi:10.1643/0045-8511(2007)2007[699:Tnvsot]2.0.Co;2")); 069 assertTrue(DOI.isParsable("https://doi.org/10.1643/0045-8511(2007)2007%5b699%3aTnvsot%5d2.0.Co%3b2")); 070 071 // try subdivisions 072 assertTrue(DOI.isParsable("http://dx.doi.org/10.1234.999/1ASCDU")); 073 assertTrue(DOI.isParsable("http://dx.doi.org/10.1234.999.123/1ASCDU")); 074 assertTrue(DOI.isParsable("http://dx.doi.org/10.1234.999.123/1ASCDU/more/and/more")); 075 assertTrue(DOI.isParsable("http://dx.doi.org/10.1234.999.123/1ASCDU.more.and/more")); 076 assertTrue(DOI.isParsable("http://dx.doi.org/10.1234.999.123/unicode-isällöwéd_h&$e")); 077 } 078 079 @Test 080 public void testCreate() { 081 DOI d = new DOI("http://dx.doi.org/10.1234/1ASCDU"); 082 083 assertSame(d, "http://dx.doi.org/urn:doi:10.1234/1ASCDU"); 084 assertSame(d, "http://doi.org/urn:doi:10.1234/1ASCDU"); 085 assertSame(d, "http://dx.doi.org/doi:10.1234/1ASCDU"); 086 assertSame(d, "http://doi.org/doi:10.1234/1ASCDU"); 087 assertSame(d, "http://dx.doi.org/10.1234/1ASCDU"); 088 assertSame(d, "http://doi.org/10.1234/1ASCDU"); 089 assertSame(d, "https://dx.doi.org/10.1234/1ASCDU"); 090 assertSame(d, "https://doi.org/10.1234/1ASCDU"); 091 092 assertSame(d, "doi:10.1234/1ASCDU"); 093 assertSame(d, "urn:doi:10.1234/1ASCDU"); 094 assertSame(d, "doi:10.1234/1ASCDU"); 095 assertSame(d, "urn:doi:10.1234/1ASCDU"); 096 assertSame(d, "doi:10.1234/1ascdu"); 097 assertSame(d, "urn:doi:10.1234/1ascdu"); 098 assertSame(d, "10.1234/1ascdu"); 099 assertSame(d, "10.1234/1ASCDU"); 100 101 new DOI("https://doi.org/10.1643/0045-8511(2007)2007%5b699%3aTnvsot%5d2.0.Co%3b2"); 102 103 // try subdivisions 104 new DOI("http://dx.doi.org/10.1234.999/1ASCDU"); 105 new DOI("http://dx.doi.org/10.1234.999.123/1ASCDU"); 106 new DOI("http://dx.doi.org/10.1234.999.123/1ASCDU/more/and/more"); 107 new DOI("http://dx.doi.org/10.1234.999.123/1ASCDU.more.and/more"); 108 new DOI("http://dx.doi.org/10.1234.999.123/unicode-isällöwéd_h&$e"); 109 110 // try invalid ones 111 assertInvalid("uri:doi:10.1234/1ascdu"); 112 assertInvalid("doi::10.1234/1ascdu"); 113 assertInvalid("10/1234/1ascdu"); 114 assertInvalid("doi"); 115 assertInvalid("Tim Robertson"); 116 assertInvalid("http://dx.doi.org"); 117 assertInvalid("http://dx.doi.org/10"); 118 assertInvalid("http://doi.org"); 119 assertInvalid("http://doi.org/10.453621432764678123"); 120 assertInvalid("http://dx.doi.org/11.1234.999/1ASCDU"); 121 } 122 123 @Test 124 public void testUrlConversion() throws Exception { 125 DOI d = new DOI("http://doi.org/10.1000/456%23789"); 126 assertEquals("456%23789", d.getSuffix()); 127 assertSame(d, "10.1000/456%23789"); 128 129 //getUrl will be returned as https (preferred http://www.doi.org/doi_handbook/3_Resolution.html) 130 assertEquals(URI.create("https://doi.org/10.1000/" + URLEncoder.encode("456%23789", "UTF-8")), d.getUrl()); 131 } 132 133 private void assertSame(DOI doi, String doi2) { 134 DOI d2 = new DOI(doi2); 135 assertEquals(d2, doi); 136 } 137 138 private void assertInvalid(String doi) { 139 try { 140 new DOI(doi); 141 fail("Invalid DOI expected: " + doi); 142 } catch (IllegalArgumentException e) { 143 // expected! 144 } 145 } 146 147 /** 148 * A container of Languages using 2 properties. 149 */ 150 private static class Container { 151 152 public DOI doi1; 153 public DOI doi2; // verify that the names don't matter 154 155 public Container(DOI doi1, DOI doi2) { 156 this.doi1 = doi1; 157 this.doi2 = doi2; 158 } 159 160 // used by serializer below 161 public Container() { 162 } 163 164 @Override 165 public boolean equals(Object o) { 166 if (this == o) { 167 return true; 168 } 169 if (o == null || getClass() != o.getClass()) { 170 return false; 171 } 172 Container container = (Container) o; 173 return Objects.equals(doi1, container.doi1) && 174 Objects.equals(doi2, container.doi2); 175 } 176 177 @Override 178 public int hashCode() { 179 return Objects.hash(doi1, doi2); 180 } 181 } 182 183 @Test 184 public void testSerDe() throws IOException { 185 DOI d = new DOI("10.1234", "1ASCDU"); 186 SerdeTestUtils.testSerDe(d, DOI.class); 187 188 Container source = new Container(new DOI("doi:10.1038/nature.2014.16460"), new DOI("http://dx.doi.org/10.1034/gbif.2014.xscdf2")); 189 try { 190 String json = SerdeTestUtils.testSerDe(source, Container.class); 191 assertFalse(json.contains("doi:10."), "DOIs should be shown without a scheme"); 192 assertFalse(json.contains("http"), "DOIs should not use http resolvers"); 193 assertFalse(json.contains("doi.org"), "DOIs should not use http resolvers"); 194 System.out.println(json); 195 } catch (Exception e) { 196 fail(e.getMessage()); 197 } 198 } 199}