From dcb4f5ce09d0d0eda44630e059223b03c713e737 Mon Sep 17 00:00:00 2001 From: eldurloki Date: Wed, 26 Nov 2014 00:21:20 +0100 Subject: [PATCH] Transformed api error to exception and moved token to post body Task: #38 --- .../sourceforge/jwbf/mediawiki/MediaWiki.java | 8 +-- .../mediawiki/actions/editing/FileUpload.java | 60 ++++++++++++------- .../actions/editing/GetApiToken.java | 1 - .../jwbf/mediawiki/bots/MediaWikiBot.java | 2 +- .../jwbf/mediawiki/contentRep/SimpleFile.java | 12 ++++ .../actions/editing/FileUploadTest.java | 43 +++++++++++++ .../resources/mediawiki/any/uploadError.xml | 4 ++ 7 files changed, 103 insertions(+), 27 deletions(-) create mode 100644 src/test/java/net/sourceforge/jwbf/mediawiki/actions/editing/FileUploadTest.java create mode 100644 src/test/resources/mediawiki/any/uploadError.xml diff --git a/src/main/java/net/sourceforge/jwbf/mediawiki/MediaWiki.java b/src/main/java/net/sourceforge/jwbf/mediawiki/MediaWiki.java index a7575c75..821af48a 100755 --- a/src/main/java/net/sourceforge/jwbf/mediawiki/MediaWiki.java +++ b/src/main/java/net/sourceforge/jwbf/mediawiki/MediaWiki.java @@ -265,9 +265,9 @@ public static String urlEncode(String s) { return urlEncodeUnchecked(s, MediaWiki.getCharset()); } - static String urlEncodeUnchecked(String s, String charset) { + static String urlEncodeUnchecked(String in, String charset) { try { - return URLEncoder.encode(s, charset); + return URLEncoder.encode(Checked.nonNull(in, "in"), charset); } catch (UnsupportedEncodingException e) { throw new IllegalArgumentException(e); } @@ -277,9 +277,9 @@ public static String urlDecode(String s) { return urlDecodeUnchecked(s, MediaWiki.getCharset()); } - static String urlDecodeUnchecked(String s, String charset) { + static String urlDecodeUnchecked(String in, String charset) { try { - return URLDecoder.decode(s, charset); + return URLDecoder.decode(Checked.nonNull(in, "in"), charset); } catch (UnsupportedEncodingException e) { throw new IllegalArgumentException(e); } diff --git a/src/main/java/net/sourceforge/jwbf/mediawiki/actions/editing/FileUpload.java b/src/main/java/net/sourceforge/jwbf/mediawiki/actions/editing/FileUpload.java index 2d1a6a00..c1388518 100644 --- a/src/main/java/net/sourceforge/jwbf/mediawiki/actions/editing/FileUpload.java +++ b/src/main/java/net/sourceforge/jwbf/mediawiki/actions/editing/FileUpload.java @@ -20,13 +20,18 @@ import java.util.Deque; +import com.google.common.base.Optional; import com.google.common.collect.Queues; import net.sourceforge.jwbf.core.actions.Post; +import net.sourceforge.jwbf.core.actions.RequestBuilder; import net.sourceforge.jwbf.core.actions.util.ActionException; import net.sourceforge.jwbf.core.actions.util.HttpAction; +import net.sourceforge.jwbf.mapper.XmlConverter; +import net.sourceforge.jwbf.mapper.XmlElement; import net.sourceforge.jwbf.mediawiki.ApiRequestBuilder; import net.sourceforge.jwbf.mediawiki.MediaWiki; import net.sourceforge.jwbf.mediawiki.actions.editing.GetApiToken.Intoken; +import net.sourceforge.jwbf.mediawiki.actions.util.ApiException; import net.sourceforge.jwbf.mediawiki.actions.util.MWAction; import net.sourceforge.jwbf.mediawiki.bots.MediaWikiBot; import net.sourceforge.jwbf.mediawiki.contentRep.SimpleFile; @@ -53,17 +58,17 @@ public class FileUpload extends MWAction { private UploadAction actionHandler; public FileUpload(final SimpleFile simpleFile, MediaWikiBot bot) { - if (!simpleFile.getFile().isFile() || !simpleFile.getFile().canRead()) { - throw new ActionException("no such file " + simpleFile.getFile()); + if (!simpleFile.isFile() || !simpleFile.canRead()) { + throw new IllegalArgumentException("no such file " + simpleFile.getFile()); } if (!bot.isLoggedIn()) { throw new ActionException("Please login first"); } - if (!simpleFile.getFile().exists()) { - throw new IllegalStateException("file not found" + simpleFile.getFile()); + if (!simpleFile.exists()) { + throw new IllegalArgumentException("file not found " + simpleFile.getFile()); } - actionHandler = new ApiUpload(simpleFile); + actionHandler = new ApiUpload(simpleFile, bot.getVersion()); actions = actionHandler.getActions(); } @@ -96,10 +101,12 @@ public String processReturningText(String xml, HttpAction hm) { private static class ApiUpload implements UploadAction { private final Deque actions = Queues.newArrayDeque(); private final SimpleFile simpleFile; + private final MediaWiki.Version version; private GetApiToken uploadTokenAction; - public ApiUpload(SimpleFile simpleFile) { + public ApiUpload(SimpleFile simpleFile, MediaWiki.Version version) { this.simpleFile = simpleFile; + this.version = version; } @Override @@ -112,22 +119,33 @@ public Deque getActions() { @Override public String handleResponse(String xml, HttpAction hm) { log.debug("{}", xml); - if (uploadTokenAction != null) { - uploadTokenAction.processReturningText(xml, hm); - Post upload = new ApiRequestBuilder() // - .action("upload") // - .formatXml() // - .param(uploadTokenAction.get().urlEncodedToken()) // - .param("filename", MediaWiki.urlEncode(simpleFile.getTitle())) // - .param("ignorewarnings", true) // - .buildPost() // - .postParam("file", simpleFile.getFile()) // - ; - actions.add(upload); - uploadTokenAction = null; // XXX + XmlElement doc = XmlConverter.getRootElementWithError(xml); + Optional exceptionOptional = doc.getErrorElement() // + .transform(XmlConverter.toApiException()); + if (exceptionOptional.isPresent()) { + throw exceptionOptional.get(); + } else { + if (uploadTokenAction != null) { + uploadTokenAction.processReturningText(xml, hm); + RequestBuilder requestBuilder = new ApiRequestBuilder() // + .action("upload") // + .formatXml() // + .param("filename", MediaWiki.urlEncode(simpleFile.getTitle())) // + .param("ignorewarnings", true) // + .postParam("file", simpleFile.getFile()); + if (version.greaterEqThen(MediaWiki.Version.MW1_24)) { + // TODO test after public release of MW1_24 + requestBuilder.postParam(uploadTokenAction.get().urlEncodedToken()); + } else { + requestBuilder.param(uploadTokenAction.get().urlEncodedToken()); + } + Post upload = requestBuilder.buildPost(); + actions.add(upload); + uploadTokenAction = null; // XXX + } + // file upload requires enabled uploads, upload rights and filesystem permisions + return xml; } - // file upload requires enabled uploads, upload rights and filesystem permisions - return xml; } } diff --git a/src/main/java/net/sourceforge/jwbf/mediawiki/actions/editing/GetApiToken.java b/src/main/java/net/sourceforge/jwbf/mediawiki/actions/editing/GetApiToken.java index 1e390673..de399914 100644 --- a/src/main/java/net/sourceforge/jwbf/mediawiki/actions/editing/GetApiToken.java +++ b/src/main/java/net/sourceforge/jwbf/mediawiki/actions/editing/GetApiToken.java @@ -110,7 +110,6 @@ public GetApiToken(Intoken intoken, String title) { * @param title title of the article to generate the urlEncodedToken for */ private static Get generateTokenRequest(Intoken intoken, String title) { - log.trace("enter GetToken.generateTokenRequest()"); return new ApiRequestBuilder() // .action("query") // .formatXml() // diff --git a/src/main/java/net/sourceforge/jwbf/mediawiki/bots/MediaWikiBot.java b/src/main/java/net/sourceforge/jwbf/mediawiki/bots/MediaWikiBot.java index b92be437..0dbcd1f2 100644 --- a/src/main/java/net/sourceforge/jwbf/mediawiki/bots/MediaWikiBot.java +++ b/src/main/java/net/sourceforge/jwbf/mediawiki/bots/MediaWikiBot.java @@ -222,7 +222,7 @@ static Optional checkTitle(String title) { /** * @return true if */ - public final boolean isLoggedIn() { + public boolean isLoggedIn() { return login != null && login.isLoggedIn(); } diff --git a/src/main/java/net/sourceforge/jwbf/mediawiki/contentRep/SimpleFile.java b/src/main/java/net/sourceforge/jwbf/mediawiki/contentRep/SimpleFile.java index cce49ee8..ad79c7a2 100644 --- a/src/main/java/net/sourceforge/jwbf/mediawiki/contentRep/SimpleFile.java +++ b/src/main/java/net/sourceforge/jwbf/mediawiki/contentRep/SimpleFile.java @@ -72,6 +72,18 @@ public File getFile() { return this.file; } + public boolean isFile() { + return getFile().isFile(); + } + + public boolean canRead() { + return getFile().canRead(); + } + + public boolean exists() { + return getFile().exists(); + } + public String getPath() { return file.getPath(); } diff --git a/src/test/java/net/sourceforge/jwbf/mediawiki/actions/editing/FileUploadTest.java b/src/test/java/net/sourceforge/jwbf/mediawiki/actions/editing/FileUploadTest.java new file mode 100644 index 00000000..5af4232f --- /dev/null +++ b/src/test/java/net/sourceforge/jwbf/mediawiki/actions/editing/FileUploadTest.java @@ -0,0 +1,43 @@ +package net.sourceforge.jwbf.mediawiki.actions.editing; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import net.sourceforge.jwbf.TestHelper; +import net.sourceforge.jwbf.core.actions.util.HttpAction; +import net.sourceforge.jwbf.mediawiki.actions.util.ApiException; +import net.sourceforge.jwbf.mediawiki.bots.MediaWikiBot; +import net.sourceforge.jwbf.mediawiki.contentRep.SimpleFile; +import org.junit.Test; + +public class FileUploadTest { + + @Test + public void testException() { + // GIVEN + MediaWikiBot bot = mock(MediaWikiBot.class); + SimpleFile simpleFile = mock(SimpleFile.class); + when(simpleFile.isFile()).thenReturn(true); + when(simpleFile.exists()).thenReturn(true); + when(simpleFile.canRead()).thenReturn(true); + when(simpleFile.getPath()).thenReturn("any"); + when(bot.isLoggedIn()).thenReturn(true); + FileUpload testee = new FileUpload(simpleFile, bot); + HttpAction action = mock(HttpAction.class); + + String xml = TestHelper.anyWikiResponse("uploadError.xml"); + + try { + // WHEN + testee.processReturningText(xml, action); + fail(); + } catch (ApiException e) { + // THEN + assertEquals("API ERROR CODE: mustposttoken VALUE: The 'token' parameter was found " // + + "in the query string, but must be in the POST body", e.getMessage()); + } + } + +} diff --git a/src/test/resources/mediawiki/any/uploadError.xml b/src/test/resources/mediawiki/any/uploadError.xml new file mode 100644 index 00000000..937f4495 --- /dev/null +++ b/src/test/resources/mediawiki/any/uploadError.xml @@ -0,0 +1,4 @@ + + + See https://commons.wikimedia.org/w/api.php for API usage +