...
 
Commits (4)
......@@ -68,8 +68,8 @@ upload to transifex:
release:
stage: deploy
environment:
name: pages branch
url: https://gitlab.com/JOSM/wikipedia/tree/pages
name: pages branch (dist directory)
url: https://gitlab.com/JOSM/wikipedia/tree/pages/dist
script:
- &clone_pages_branch |
echo "$SSH_PRIVATE_DEPLOY_KEY" > ~/.ssh/id_rsa
......@@ -99,13 +99,13 @@ release:
publish master update site:
stage: deploy
environment:
name: master update site
url: https://josm.gitlab.io/wikipedia/snapshot/master/update-site
name: pages branch (snapshot update site)
url: https://gitlab.com/JOSM/wikipedia/tree/pages
script:
- *clone_pages_branch
- |
commitHash=`git rev-parse HEAD`
commitMessage="Make latest commit available via JOSM update site (master@$commitHash)"
commitMessage="Make latest commit from master available via JOSM update site ($commitHash)"
- |
rm -vrf pages/snapshot/master
mkdir -pv pages/snapshot/master
......
......@@ -18,6 +18,7 @@ import org.wikipedia.actions.WikipediaAddNamesAction;
import org.wikipedia.actions.WikipediaCopyTemplate;
import org.wikipedia.gui.SophoxDownloadReader;
import org.wikipedia.gui.WikiPreferences;
import org.wikipedia.gui.WikidataInfoToggleDialog;
import org.wikipedia.gui.WikidataItemSearchDialog;
import org.wikipedia.gui.WikidataTagCellRenderer;
import org.wikipedia.gui.WikipediaToggleDialog;
......@@ -64,7 +65,9 @@ public final class WikipediaPlugin extends Plugin {
@Override
public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
if (newFrame != null) {
newFrame.addToggleDialog(new WikipediaToggleDialog());
final WikipediaToggleDialog wikiDialog = new WikipediaToggleDialog();
newFrame.addToggleDialog(wikiDialog);
newFrame.addToggleDialog(new WikidataInfoToggleDialog(wikiDialog));
newFrame.propertiesDialog.addCustomPropertiesCellRenderer(new WikidataTagCellRenderer());
}
}
......
package org.wikipedia.api;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;
import java.util.Objects;
public abstract class CustomDeserializer<T> extends StdDeserializer<T> {
private final ObjectMapper mapper;
protected CustomDeserializer(final ObjectMapper mapper) {
super((Class<?>) null);
this.mapper = Objects.requireNonNull(mapper);
}
@Override
public final T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
return deserialize(p.getCodec().readTree(p), mapper);
}
public abstract T deserialize(final JsonNode node, final ObjectMapper mapper) throws JsonProcessingException;
}
......@@ -12,6 +12,7 @@ import org.wikipedia.api.ApiQuery;
import org.wikipedia.api.ApiUrl;
import org.wikipedia.api.SerializationSchema;
import org.wikipedia.api.wikidata_action.json.SitematrixResult;
import org.wikipedia.api.wikidata_action.json.WbgetclaimsResult;
import org.wikipedia.api.wikidata_action.json.WbgetentitiesResult;
import org.wikipedia.tools.RegexUtil;
......@@ -87,6 +88,16 @@ public final class WikidataActionApiQuery<T> extends ApiQuery<T> {
);
}
public static WikidataActionApiQuery<WbgetclaimsResult> wbgetclaims(final String qId) {
if (!RegexUtil.isValidQId(qId)) {
throw new IllegalArgumentException("Invalid Q-ID: " + qId);
}
return new WikidataActionApiQuery<>(
FORMAT_PARAMS + "&action=wbgetclaims&props=&entity=" + qId,
WbgetclaimsResult.SCHEMA
);
}
@Override
public String getCacheKey() {
return getUrl().toString() + '?' + getQueryString();
......
......@@ -16,7 +16,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import org.wikipedia.api.SerializationSchema;
......
package org.wikipedia.gui;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
class StatementPanel extends JPanel {
private final JLabel propertyLabel = new JLabel();
private final List<JLabel> valueLabels = new ArrayList<>();
private final GridBagConstraints constraints = new GridBagConstraints();
StatementPanel(final String propertyName, final String... valueNames) {
initLayout();
setPropertyName(propertyName);
setValueNames(valueNames);
}
private void initLayout() {
setBorder(new LineBorder(new Color(0xc8ccd1), 1));
propertyLabel.setFont(propertyLabel.getFont().deriveFont(Font.BOLD));
propertyLabel.setForeground(Color.BLACK);
propertyLabel.setBackground(new Color(0xeaecf0));
propertyLabel.setOpaque(true);
propertyLabel.setHorizontalAlignment(JLabel.TRAILING);
setBackground(new Color(0xeaecf0));
setLayout(new GridBagLayout());
constraints.weightx = 0;
constraints.anchor = GridBagConstraints.CENTER;
constraints.fill = GridBagConstraints.BOTH;
constraints.ipadx = 20;
constraints.ipady = constraints.ipadx / 2;
constraints.gridx = 0;
constraints.gridy = 0;
add(propertyLabel, constraints);
}
private void setPropertyName(final String propertyName) {
this.propertyLabel.setText(propertyName);
}
private synchronized void setValueNames(final String[] valueNames) {
constraints.gridx = 1;
constraints.weightx = 1;
for (int i = 0; i < Math.max(valueNames.length, valueLabels.size()); i++) {
if (i >= valueNames.length) {
final JLabel currentLabel = valueLabels.get(i);
remove(currentLabel);
valueLabels.remove(currentLabel);
} else if (i >= valueLabels.size()) {
final JLabel currentLabel = new JLabel(valueNames[i], JLabel.LEADING);
currentLabel.setFont(currentLabel.getFont().deriveFont(Font.PLAIN));
currentLabel.setBackground(Color.WHITE);
currentLabel.setForeground(Color.BLACK);
currentLabel.setOpaque(true);
valueLabels.add(currentLabel);
constraints.gridy = i;
add(currentLabel, constraints);
} else {
final JLabel currentLabel = valueLabels.get(i);
currentLabel.setText(valueNames[i]);
}
}
}
}
// License: GPL. For details, see LICENSE file.
package org.wikipedia.gui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import org.openstreetmap.josm.data.osm.DataSelectionListener;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
import org.openstreetmap.josm.data.osm.event.DataSetListener;
import org.openstreetmap.josm.data.osm.event.DataSetListenerAdapter;
import org.openstreetmap.josm.gui.MainApplication;
import org.openstreetmap.josm.gui.Notification;
import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
import org.openstreetmap.josm.tools.GBC;
import org.openstreetmap.josm.tools.I18n;
import org.openstreetmap.josm.tools.OpenBrowser;
import org.wikipedia.WikipediaPlugin;
import org.wikipedia.data.WikidataEntry;
import org.wikipedia.data.WikipediaEntry;
import org.wikipedia.tools.OsmPrimitiveUtil;
public class WikidataInfoToggleDialog extends ToggleDialog {
private static final Logger L = Logger.getLogger(WikidataInfoToggleDialog.class.getName());
private static final String EMPTY_STRING = "";
private final WikipediaToggleDialog wikiDialog;
private final JPanel mainPanel = new JPanel(new GridLayout(1, 1));
private final JLabel messageLabel = new JLabel();
private final JPanel messagePanel = new JPanel(new BorderLayout());
private final JLabel nameLabel = new JLabel();
private final JLabel descriptionLabel = new JLabel();
private final JLabel qidLabel = new JLabel();
private final JPanel infoPanel = new JPanel(new BorderLayout());
private final JTabbedPane tabs = new JTabbedPane();
private final JPanel labelTab = new JPanel();
private final JPanel statementTab = new JPanel();
private final JPanel linkTab = new JPanel();
private final JButton webLinkButton = new JButton();
private final DataSelectionListener selectionListener = it -> updateSelection();
private final DataSetListener datasetListener = new DataSetListenerAdapter(it -> {
if (it.getType() == AbstractDatasetChangedEvent.DatasetEventType.TAGS_CHANGED) {
updateSelection();
}
});
public WikidataInfoToggleDialog(final WikipediaToggleDialog wikiDialog) {
super(
I18n.tr("Wikidata Info"),
"wikidata",
I18n.tr("Show properties of the selected Wikidata item"),
null,
150
);
createLayout(mainPanel, false, Collections.emptyList());
this.wikiDialog = Objects.requireNonNull(wikiDialog);
messageLabel.setForeground(Color.DARK_GRAY);
messageLabel.setFont(messageLabel.getFont().deriveFont(Font.ITALIC));
messagePanel.setBackground(Color.WHITE);
messagePanel.add(messageLabel, BorderLayout.CENTER);
// Set up info panel
final JPanel basicInfoPanel = new JPanel(new BorderLayout());
final JPanel namePanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
nameLabel.setFont(nameLabel.getFont().deriveFont(nameLabel.getFont().getSize() * 1.25f));
namePanel.add(nameLabel);
qidLabel.setForeground(Color.DARK_GRAY);
qidLabel.setFont(qidLabel.getFont().deriveFont(Font.ITALIC));
namePanel.add(qidLabel);
basicInfoPanel.add(namePanel, BorderLayout.CENTER);
descriptionLabel.setFont(descriptionLabel.getFont().deriveFont(Font.PLAIN));
basicInfoPanel.add(descriptionLabel, BorderLayout.SOUTH);
infoPanel.add(basicInfoPanel, BorderLayout.NORTH);
infoPanel.add(tabs, BorderLayout.CENTER);
// Set up statement tab
statementTab.setLayout(new GridBagLayout());
final GridBagConstraints constraints = new GridBagConstraints();
constraints.anchor = GridBagConstraints.NORTH;
constraints.gridx = 0;
constraints.gridy = 0;
constraints.insets = new Insets(1, 1, 1, 1);
constraints.fill = GridBagConstraints.BOTH;
// At the moment only dummy content
constraints.weightx = 1;
statementTab.add(new StatementPanel("instance of", "example", "dummy content"), constraints);
constraints.gridy++;
statementTab.add(new StatementPanel("start date", "42"), constraints);
constraints.gridy++;
statementTab.add(new StatementPanel("architect", "John Doe"), constraints);
constraints.gridy++;
constraints.weighty = 1;
statementTab.add(GBC.glue(0, 0), constraints);
linkTab.add(webLinkButton);
tabs.add(I18n.tr("Statements"), statementTab);
tabs.add(I18n.tr("Labels"), labelTab);
tabs.add(I18n.tr("Links"), linkTab);
// Set up listeners
this.wikiDialog.list.addListSelectionListener(event -> updateSelection());
MainApplication.getLayerManager().addAndFireActiveLayerChangeListener(event -> {
System.out.println("Fire active layer change");
final DataSet previous = event.getPreviousDataSet();
final DataSet current = event.getSource().getActiveDataSet();
if (previous != null) {
previous.removeDataSetListener(datasetListener);
previous.removeSelectionListener(selectionListener);
}
if (current != null) {
current.addSelectionListener(selectionListener);
current.addDataSetListener(datasetListener);
}
});
updateSelection();
}
/**
* @param qID the Q-ID of the selected wikidata item
*/
@Override
public void setTitle(final String qID) {
super.setTitle(qID == null ? I18n.tr("Wikidata info") : I18n.tr("Wikidata info: {0}", qID));
}
/**
* Whenever it is possible that the content of the info panel should be updated, call this method.
* It checks for the currently selected items in the active dataset and in the Wikidata list. The panel is updated.
*/
private void updateSelection() {
mainPanel.removeAll();
final DataSet dataset = MainApplication.getLayerManager().getActiveDataSet();
final Map<String, Integer> wdTagsInDataset =
dataset == null
? Collections.emptyMap()
: dataset.getSelected().stream()
.map(OsmPrimitiveUtil::getWikidataValue)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.groupingBy(it -> it, Collectors.summingInt(it -> 1)));
if (wdTagsInDataset.isEmpty()) {
final WikipediaEntry entry = this.wikiDialog.list.getSelectedValue();
if (entry instanceof WikidataEntry) {
setTitle(entry.article);
nameLabel.setText(((WikidataEntry) entry).label);
descriptionLabel.setText(((WikidataEntry) entry).description);
qidLabel.setText(entry.article);
mainPanel.add(new JScrollPane(infoPanel));
} else {
setTitle(null);
messageLabel.setText(I18n.tr("No Wikidata item is selected!"));
mainPanel.add(messagePanel);
}
} else if (wdTagsInDataset.size() >= 2) {
final String itemList = wdTagsInDataset.entrySet().stream().map(it -> it.getKey() + " (" + it.getValue() + "×)").collect(Collectors.joining(", "));
setTitle(itemList);
messageLabel.setText(I18n.tr("More than one OSM object is selected: {0}", itemList));
mainPanel.add(messagePanel);
} else { // size == 1
final String qId = wdTagsInDataset.keySet().iterator().next();
setTitle(qId);
nameLabel.setText(EMPTY_STRING);
descriptionLabel.setText(EMPTY_STRING);
qidLabel.setText(qId);
mainPanel.add(new JScrollPane(infoPanel));
webLinkButton.setAction(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
final String uri = "https://www.wikidata.org/wiki/" + qId;
final String error = OpenBrowser.displayUrl(uri);
if (error != null) {
new Notification(I18n.tr("Can't open website {0} in browser! Error message: {1}", uri, error)).setIcon(WikipediaPlugin.W_IMAGE.get()).show();
}
}
});
webLinkButton.setText(I18n.tr("Open item {0} in browser", qId));
}
mainPanel.revalidate();
mainPanel.repaint();
}
}
......@@ -13,6 +13,7 @@ import org.wikipedia.data.WikipediaSite;
public final class OsmPrimitiveUtil {
private static final Pattern WIKIPEDIA_PATTERN = Pattern.compile("(.+):(.+)");
public static final String TAG_NAME_WIKIPEDIA = "wikipedia";
private static final String TAG_NAME_WIKIDATA = "wikidata";
private OsmPrimitiveUtil() {
// Private constructor to avoid instantiation
......@@ -43,4 +44,9 @@ public final class OsmPrimitiveUtil {
}
return Optional.empty();
}
public static Optional<String> getWikidataValue(final OsmPrimitive primitive) {
final String wikidataValue = primitive.get(TAG_NAME_WIKIDATA);
return Optional.ofNullable(RegexUtil.isValidQId(wikidataValue) ? wikidataValue : null);
}
}
......@@ -4,6 +4,7 @@ package org.wikipedia.tools;
import java.util.regex.Pattern;
public class RegexUtil {
private static final Pattern PROPERTY_ID_PATTERN = Pattern.compile("^P[1-9][0-9]*$");
private static final Pattern Q_ID_PATTERN = Pattern.compile("^Q[1-9][0-9]*$");
private static final Pattern SITE_ID_PATTERN = Pattern.compile("^[a-z][a-z][a-z]?wiki$");
public static final Pattern WIKIPEDIA_TAG_VALUE_PATTERN = Pattern.compile("([a-z][a-z][a-z]?):(.+)");
......@@ -14,6 +15,10 @@ public class RegexUtil {
// Private constructor to avoid instantiation
}
public static boolean isValidPropertyId(final String value) {
return value != null && PROPERTY_ID_PATTERN.matcher(value).matches();
}
public static boolean isValidQId(final String value) {
return value != null && Q_ID_PATTERN.matcher(value).matches();
}
......
package org.wikipedia.api.wdq;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.Rule;
import org.junit.Test;
import org.openstreetmap.josm.testutils.JOSMTestRules;
......@@ -70,7 +68,7 @@ public class WdqApiQueryTest {
testFindInstancesOfClassesOrTheirSubclasses(MIXED_LIST, Collections.singletonList(BUILDING_CLASS), BUILDING_LIST);
}
private void testFindInstancesOfClassesOrTheirSubclasses(final Collection<String> itemList, final Collection<String> classesList, final Collection<String> expectedResultList) throws IOException {
private static void testFindInstancesOfClassesOrTheirSubclasses(final Collection<String> itemList, final Collection<String> classesList, final Collection<String> expectedResultList) throws IOException {
final SparqlResult result = ApiQueryClient.query(WdqApiQuery.findInstancesOfClassesOrTheirSubclasses(itemList, classesList));
for (final String expectedEntry : expectedResultList) {
assertEquals("Entry " + expectedEntry + " not found in the result!", 1, result.getRows().stream().filter(row -> ("http://www.wikidata.org/entity/" + expectedEntry).equals(row.get(0).getValue())).count());
......
package org.wikipedia.api.wikidata_action;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.github.tomakehurst.wiremock.matching.EqualToPattern;
import java.net.MalformedURLException;
import java.net.URL;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.openstreetmap.josm.testutils.JOSMTestRules;
public abstract class AbstractWikidataActionApiTest {
@Rule
public WireMockRule wmRule = new WireMockRule(wireMockConfig().dynamicPort());
@Rule
public JOSMTestRules josmRule = new JOSMTestRules().preferences();
private URL oldDefaultUrl = null;
@Before
public void before() throws MalformedURLException {
oldDefaultUrl = setApiUrl(new URL("http://localhost:" + wmRule.port()));
}
@After
public void after() {
setApiUrl(oldDefaultUrl);
}
/**
* Sets {@link WikidataActionApiQuery#defaultUrl} to the supplied URL
* @param url the new URL
* @return the URL to which {@link WikidataActionApiQuery#defaultUrl} was set before
*/
private static URL setApiUrl(final URL url) {
final URL prevURL = WikidataActionApiQuery.defaultUrl;
WikidataActionApiQuery.defaultUrl = url;
return prevURL;
}
protected static void simpleJsonStub(final byte[] bytes) {
stubFor(post("/")
.withHeader("Accept", equalTo("application/json"))
.willReturn(
aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody(bytes)
)
);
}
protected static void simpleRequestVerify(final String expectedQueryString) {
verify(postRequestedFor(urlEqualTo("/")).withRequestBody(new EqualToPattern(expectedQueryString)));
}
}
package org.wikipedia.api.wikidata_action;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.junit.Test;
import org.wikipedia.api.ApiQueryClient;
import org.wikipedia.api.wikidata_action.json.WbgetclaimsResult;
import org.wikipedia.testutils.ResourceFileLoader;
public class WbgetclaimsTest extends AbstractWikidataActionApiTest {
@Test
public void test() throws IOException, URISyntaxException {
simpleJsonStub(ResourceFileLoader.getResourceBytes(WikidataActionApiQueryTest.class, "response/wbgetclaims/Q2.json"));
final WbgetclaimsResult result = ApiQueryClient.query(WikidataActionApiQuery.wbgetclaims("Q2"));
assertEquals(216, result.getClaims().size()); // Total number of claims
assertEquals(WbgetclaimsResult.Claim.RANK.PREFERRED, result.getClaims().stream().filter(it -> "Q2$9bbb058a-48ab-0a81-e88e-82bba6b2abe5".equals(it.getId())).findFirst().get().getRank());
assertEquals("P31", result.getClaims().stream().filter(it -> "Q2$50fad68d-4f91-f878-6f29-e655af54690e".equals(it.getId())).findFirst().get().getMainSnak().getProperty());
final Map<String, List<WbgetclaimsResult.Claim>> claimMap = result.getClaims().stream().collect(Collectors.groupingBy(it -> it.getMainSnak().getProperty()));
assertEquals(97, claimMap.keySet().size()); // Number of different properties for which claims exist
simpleRequestVerify("format=json&utf8=1&formatversion=1&action=wbgetclaims&props=&entity=Q2");
}
}
// License: GPL. For details, see LICENSE file.
package org.wikipedia.api.wikidata_action;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.github.tomakehurst.wiremock.matching.EqualToPattern;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.openstreetmap.josm.testutils.JOSMTestRules;
import org.wikipedia.api.ApiQueryClient;
import org.wikipedia.api.wikidata_action.json.WbgetentitiesResult;
import org.wikipedia.testutils.ResourceFileLoader;
public class WikidataActionApiQueryTest {
@Rule
public WireMockRule wmRule = new WireMockRule(wireMockConfig().dynamicPort());
@Rule
public JOSMTestRules josmRule = new JOSMTestRules().preferences();
private URL oldDefaultUrl = null;
@Before
public void before() throws MalformedURLException {
oldDefaultUrl = setApiUrl(new URL("http://localhost:" + wmRule.port()));
}
@After
public void after() {
setApiUrl(oldDefaultUrl);
}
public class WikidataActionApiQueryTest extends AbstractWikidataActionApiTest {
@Test(expected = IllegalArgumentException.class)
public void testWbgetentities_nonQId() {
WikidataActionApiQuery.wbgetentities(Collections.singletonList("X1"));
}
@Test(expected = IllegalArgumentException.class)
public void testCheckEntityExists_nonQId2() {
WikidataActionApiQuery.wbgetentities(Arrays.asList("Q1", "Q2", "X1"));
}
......@@ -70,6 +37,22 @@ public class WikidataActionApiQueryTest {
WikidataActionApiQuery.wbgetentities(Collections.emptyList());
}
@Test(expected = IllegalArgumentException.class)
public void testWbgetentitiesLabels_invalidQid() {
WikidataActionApiQuery.wbgetentitiesLabels("X1");
}
@Test
public void testApiName() {
assertEquals("Wikidata Action API", WikidataActionApiQuery.wbgetclaims("Q1").getApiName());
assertEquals("Wikidata Action API", WikidataActionApiQuery.sitematrix().getApiName());
}
@Test(expected = IllegalArgumentException.class)
public void testWbgetclaims_invalidQid() {
WikidataActionApiQuery.wbgetclaims("123");
}
@Test
public void testWbgetentitiesQuery() {
assertEquals(
......@@ -84,16 +67,7 @@ public class WikidataActionApiQueryTest {
@Test
public void testWikidataForArticles1() throws IOException, URISyntaxException {
stubFor(post("/")
.withHeader("Accept", equalTo("application/json"))
.willReturn(
aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody(ResourceFileLoader.getResourceBytes(WikidataActionApiQueryTest.class, "response/wbgetentities/dewiki_Berlin.json"))
)
);
simpleJsonStub(ResourceFileLoader.getResourceBytes(WikidataActionApiQueryTest.class, "response/wbgetentities/dewiki_Berlin.json"));
final WbgetentitiesResult result = ApiQueryClient.query(WikidataActionApiQuery.wbgetentities("dewiki", Collections.singletonList("Berlin")));
......@@ -109,20 +83,12 @@ public class WikidataActionApiQueryTest {
assertEquals("dewiki", sitelinks.iterator().next().getSite());
assertEquals("Berlin", sitelinks.iterator().next().getTitle());
verify(postRequestedFor(urlEqualTo("/")).withRequestBody(new EqualToPattern("format=json&utf8=1&formatversion=1&action=wbgetentities&props=sitelinks&sites=dewiki&sitefilter=dewiki&titles=Berlin")));
simpleRequestVerify("format=json&utf8=1&formatversion=1&action=wbgetentities&props=sitelinks&sites=dewiki&sitefilter=dewiki&titles=Berlin");
}
@Test
public void testWikidataForArticles2() throws IOException, URISyntaxException {
stubFor(post("/")
.withHeader("Accept", equalTo("application/json"))
.willReturn(
aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody(ResourceFileLoader.getResourceBytes(WikidataActionApiQueryTest.class, "response/wbgetentities/enwiki_2entities2missing.json"))
)
);
simpleJsonStub(ResourceFileLoader.getResourceBytes(WikidataActionApiQueryTest.class, "response/wbgetentities/enwiki_2entities2missing.json"));
final WbgetentitiesResult result = ApiQueryClient.query(WikidataActionApiQuery.wbgetentities("enwiki", Arrays.asList("United States", "missing-article", "Great Britain", "Another missing article")));
......@@ -148,20 +114,12 @@ public class WikidataActionApiQueryTest {
assertNull(missing2.getId());
assertEquals("enwiki", missing2.getSite());
verify(postRequestedFor(urlEqualTo("/")).withRequestBody(new EqualToPattern("format=json&utf8=1&formatversion=1&action=wbgetentities&props=sitelinks&sites=enwiki&sitefilter=enwiki&titles=United+States%7Cmissing-article%7CGreat+Britain%7CAnother+missing+article")));
simpleRequestVerify("format=json&utf8=1&formatversion=1&action=wbgetentities&props=sitelinks&sites=enwiki&sitefilter=enwiki&titles=United+States%7Cmissing-article%7CGreat+Britain%7CAnother+missing+article");
}
@Test
public void testWikidataItemLabelQuery() throws IOException, URISyntaxException {
stubFor(post("/")
.withHeader("Accept", equalTo("application/json"))
.willReturn(
aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody(ResourceFileLoader.getResourceBytes(WikidataActionApiQueryTest.class, "response/wbgetentities/labels_Q42.json"))
)
);
simpleJsonStub(ResourceFileLoader.getResourceBytes(WikidataActionApiQueryTest.class, "response/wbgetentities/labels_Q42.json"));
final Map<String, String> result = ApiQueryClient.query(WikidataActionApiQuery.wbgetentitiesLabels("Q42"));
assertEquals(138, result.size());
......@@ -171,18 +129,7 @@ public class WikidataActionApiQueryTest {
assertEquals("더글러스 애덤스", result.get("ko"));
assertEquals("ಡಾಗ್ಲಸ್ ಆಡಮ್ಸ್", result.get("tcy"));
verify(postRequestedFor(urlEqualTo("/")).withRequestBody(new EqualToPattern("format=json&utf8=1&formatversion=1&action=wbgetentities&props=labels&ids=Q42")));
}
/**
* Sets {@link WikidataActionApiQuery#defaultUrl} to the supplied URL
* @param url the new URL
* @return the URL to which {@link WikidataActionApiQuery#defaultUrl} was set before
*/
public static URL setApiUrl(final URL url) {
final URL prevURL = WikidataActionApiQuery.defaultUrl;
WikidataActionApiQuery.defaultUrl = url;
return prevURL;
simpleRequestVerify("format=json&utf8=1&formatversion=1&action=wbgetentities&props=labels&ids=Q42");
}
}
// License: GPL. For details, see LICENSE file.
package org.wikipedia.data;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static org.junit.Assert.assertEquals;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.openstreetmap.josm.testutils.JOSMTestRules;
import org.wikipedia.api.wikidata_action.AbstractWikidataActionApiTest;
import org.wikipedia.api.wikidata_action.WikidataActionApiQueryTest;
import org.wikipedia.testutils.ResourceFileLoader;
public class WikipediaSiteTest {
@Rule
public WireMockRule wmRule = new WireMockRule(wireMockConfig().dynamicPort());
@Rule
public final JOSMTestRules rules = new JOSMTestRules().preferences();
private URL oldDefaultUrl;
@Before
public void before() throws IOException, URISyntaxException {
oldDefaultUrl = WikidataActionApiQueryTest.setApiUrl(new URL("http://localhost:" + wmRule.port()));
stubFor(post("/")
.withHeader("Accept", equalTo("application/json"))
.willReturn(
aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody(ResourceFileLoader.getResourceBytes(WikidataActionApiQueryTest.class, "response/sitematrix/sitematrix.json"))
)
);
}
@After
public void after() {
WikidataActionApiQueryTest.setApiUrl(oldDefaultUrl);
}
public class WikipediaSiteTest extends AbstractWikidataActionApiTest {
@Test
public void testSites() throws IOException {
public void testSites() throws IOException, URISyntaxException {
simpleJsonStub(ResourceFileLoader.getResourceBytes(WikidataActionApiQueryTest.class, "response/sitematrix/sitematrix.json"));
assertEquals("https://de.wikipedia.org", new WikipediaSite("de").getSite().getUrl());
assertEquals("https://simple.wikipedia.org", new WikipediaSite("simple").getSite().getUrl());
assertEquals("https://be-tarask.wikipedia.org", new WikipediaSite("be-x-old").getSite().getUrl());
......@@ -60,7 +24,8 @@ public class WikipediaSiteTest {
}
@Test(expected = IllegalArgumentException.class)
public void testUnknownSite() throws IOException {
public void testUnknownSite() throws IOException, URISyntaxException {
simpleJsonStub(ResourceFileLoader.getResourceBytes(WikidataActionApiQueryTest.class, "response/sitematrix/sitematrix.json"));
new WikipediaSite("xy");
}
}