diff --git a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyException.java b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyException.java index 02b1f13b689..98160a37488 100644 --- a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyException.java +++ b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/SurveyException.java @@ -31,7 +31,8 @@ public enum ErrorCode { E_BAD_VALUE, E_BAD_XPATH, E_NO_OLD_VOTES, - E_PERMANENT_VOTE_NO_FORUM; + E_PERMANENT_VOTE_NO_FORUM, + E_VOTE_NOT_ACCEPTED; } private final ErrorCode err_code; diff --git a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/STError.java b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/STError.java index 225061fad25..4ba276dc3f8 100644 --- a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/STError.java +++ b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/STError.java @@ -1,6 +1,8 @@ package org.unicode.cldr.web.api; import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.unicode.cldr.web.SurveyException; import org.unicode.cldr.web.SurveyException.ErrorCode; @@ -64,7 +66,27 @@ public void setMessage(String message) { * @return */ public Response build() { - return Response.serverError().entity(this).build(); + return Response.status(getStatus()).entity(this).build(); + } + + /** the error as a Status */ + public Status getStatus() { + switch(code) { + case E_BAD_LOCALE: + case E_BAD_SECTION: + case E_BAD_XPATH: + return Response.Status.NOT_FOUND; + case E_NO_PERMISSION: + return Response.Status.FORBIDDEN; + case E_BAD_VALUE: + case E_VOTE_NOT_ACCEPTED: + return Response.Status.NOT_ACCEPTABLE; + case E_SESSION_DISCONNECTED: + case E_NOT_LOGGED_IN: + return Response.Status.UNAUTHORIZED; + default: + return Response.Status.INTERNAL_SERVER_ERROR; + } } public static Response surveyNotQuiteReady() { diff --git a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/VoteAPIHelper.java b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/VoteAPIHelper.java index 4a189ca3477..d154b0dfeca 100644 --- a/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/VoteAPIHelper.java +++ b/tools/cldr-apps/src/main/java/org/unicode/cldr/web/api/VoteAPIHelper.java @@ -372,18 +372,33 @@ private static Dashboard.ReviewNotification[] getOnePathDash( // separated from // the HTTP response concerns, so that VoteAPI and XPathAlt can share code without the // awkwardness of forbiddenIsOk. - static Response handleVote( + public static Response handleVote( String loc, String xp, String value, int voteLevelChanged, final CookieSession mySession, boolean forbiddenIsOk) { + // translate this call into jax-rs Response + try { + final VoteResponse r = getHandleVoteResponse(loc, xp, value, voteLevelChanged, mySession, forbiddenIsOk); + return Response.ok(r).build(); + } catch (Throwable se) { + return new STError(se).build(); + } + } + /** this function is the implementation of handleVote() but does not use any jax-rs, for unit tests */ + public static VoteResponse getHandleVoteResponse(String loc, + String xp, + String value, + int voteLevelChanged, + final CookieSession mySession, + boolean forbiddenIsOk) throws SurveyException { VoteResponse r = new VoteResponse(); mySession.userDidAction(); CLDRLocale locale = CLDRLocale.getInstance(loc); if (!UserRegistry.userCanModifyLocale(mySession.user, locale)) { - return Response.status(Status.FORBIDDEN).build(); + throw new SurveyException(ErrorCode.E_NO_PERMISSION, "Not allowed to modify " + locale); } loc = locale.getBaseName(); // sanitized final SurveyMain sm = CookieSession.sm; @@ -445,15 +460,13 @@ static Response handleVote( } } catch (Throwable t) { SurveyLog.logException(logger, t, "Processing submission " + locale + ":" + xp); - return (new STError(t).build()); + throw new SurveyException(ErrorCode.E_INTERNAL, "Processing submission " + locale + ":" + xp); } } if (!forbiddenIsOk && r.statusAction.isForbidden()) { - return Response.status(Response.Status.NOT_ACCEPTABLE) - .entity(new STError("Status action is forbidden: " + r.statusAction)) - .build(); + throw new SurveyException(ErrorCode.E_VOTE_NOT_ACCEPTED, "Status action is forbidden: " + r.statusAction); } - return Response.ok(r).build(); + return r; } private static void normalizedToZeroLengthError(VoteResponse r, List result) { diff --git a/tools/cldr-apps/src/test/java/org/unicode/cldr/unittest/web/TestSTFactory.java b/tools/cldr-apps/src/test/java/org/unicode/cldr/unittest/web/TestSTFactory.java index 8d3ac0d5d30..5936ed1c2a9 100644 --- a/tools/cldr-apps/src/test/java/org/unicode/cldr/unittest/web/TestSTFactory.java +++ b/tools/cldr-apps/src/test/java/org/unicode/cldr/unittest/web/TestSTFactory.java @@ -10,8 +10,13 @@ import java.util.Date; import java.util.Map; import java.util.TreeMap; + +import javax.ws.rs.core.Response; + import org.unicode.cldr.draft.FileUtilities; +import org.unicode.cldr.test.CheckCLDR; import org.unicode.cldr.unittest.web.TestAll.WebTestInfo; +import org.unicode.cldr.util.CLDRConfig; import org.unicode.cldr.util.CLDRFile; import org.unicode.cldr.util.CLDRFile.DraftStatus; import org.unicode.cldr.util.CLDRLocale; @@ -28,6 +33,7 @@ import org.unicode.cldr.web.BallotBox; import org.unicode.cldr.web.BallotBox.InvalidXPathException; import org.unicode.cldr.web.BallotBox.VoteNotAcceptedException; +import org.unicode.cldr.web.SurveyMain.Phase; import org.unicode.cldr.web.CookieSession; import org.unicode.cldr.web.DBUtils; import org.unicode.cldr.web.STFactory; @@ -36,6 +42,8 @@ import org.unicode.cldr.web.UserRegistry; import org.unicode.cldr.web.UserRegistry.LogoutException; import org.unicode.cldr.web.UserRegistry.User; +import org.unicode.cldr.web.api.VoteAPI; +import org.unicode.cldr.web.api.VoteAPIHelper; import org.unicode.cldr.web.XPathTable; public class TestSTFactory extends TestFmwk { @@ -453,6 +461,8 @@ public void TestVettingDataDriven() throws SQLException, IOException { public void TestVotePerf() throws SQLException, IOException { if (TestAll.skipIfNoDb()) return; + final CheckCLDR.Phase p = CLDRConfig.getInstance().getPhase(); + assertTrue("phase " + p + ".isUnitTest()", p.isUnitTest()); runDataDrivenTest("TestVotePerf"); // TestSTFactory.xml } @@ -550,6 +560,36 @@ public void handlePathValue(String path, String value) { + xpath); } break; + case "apivote": + case "apiunvote": + { + UserRegistry.User u = getUserFromAttrs(attrs, "name"); + CLDRLocale locale = CLDRLocale.getInstance(attrs.get("locale")); + boolean needException = + getBooleanAttr(attrs, "exception", false); + if (elem.equals("apiunvote")) { + value = null; + } + final CookieSession mySession = CookieSession.newSession(u, "999.999.999.999"); + try { + final VoteAPI.VoteResponse r = VoteAPIHelper.getHandleVoteResponse(locale.getBaseName(), xpath, value, 0, mySession, false); + final boolean isOk = r.didVote; + final boolean asExpected = (isOk == !needException); + if (!asExpected) { + errln("exception=" + needException + " but got status " + r.didNotSubmit + " - " + r.toString()); + } else { + logln(" status = " + r.didNotSubmit); + } + } catch(Throwable iae) { + if (needException == true) { + logln("Caught expected: " + iae); + } else { + iae.printStackTrace(); + errln("Unexpected exception: " + iae); + } + } + } + break; case "vote": case "unvote": { @@ -592,6 +632,7 @@ public void handlePathValue(String path, String value) { logln(u + " " + elem + "d for " + xpath + " = " + value); } break; + case "apiverify": // TODO case "verify": { value = value.trim(); diff --git a/tools/cldr-apps/src/test/resources/org/unicode/cldr/unittest/web/data/TestSTFactory.dtd b/tools/cldr-apps/src/test/resources/org/unicode/cldr/unittest/web/data/TestSTFactory.dtd index efb55401fab..037c60fcf24 100644 --- a/tools/cldr-apps/src/test/resources/org/unicode/cldr/unittest/web/data/TestSTFactory.dtd +++ b/tools/cldr-apps/src/test/resources/org/unicode/cldr/unittest/web/data/TestSTFactory.dtd @@ -8,7 +8,7 @@ THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. --> - + @@ -23,6 +23,20 @@ Except as contained in this notice, the name of a copyright holder shall not be + + + + + + + + + + + + + + @@ -35,6 +49,13 @@ Except as contained in this notice, the name of a copyright holder shall not be + + + + + + + diff --git a/tools/cldr-apps/src/test/resources/org/unicode/cldr/unittest/web/data/TestVotePerf.xml b/tools/cldr-apps/src/test/resources/org/unicode/cldr/unittest/web/data/TestVotePerf.xml index c9ac24ea9c7..3d4a93ed041 100644 --- a/tools/cldr-apps/src/test/resources/org/unicode/cldr/unittest/web/data/TestVotePerf.xml +++ b/tools/cldr-apps/src/test/resources/org/unicode/cldr/unittest/web/data/TestVotePerf.xml @@ -7,39 +7,69 @@ - Territory-001 - Territory-002 - Territory-003 - Territory-005 - Territory-009 - Territory-011 - Territory-013 - Territory-014 - Territory-015 - Territory-017 - Territory-018 - Territory-019 - Territory-021 - Territory-029 - Territory-030 - Territory-034 - Territory-035 - Territory-039 - Territory-053 - Territory-054 - Territory-057 - Territory-061 - Territory-142 - Territory-143 - Territory-145 - Territory-150 - Territory-151 - Territory-154 - Territory-155 - Territory-202 - Territory-419 + Territory-001 + Territory-002 + Territory-003 + Territory-005 + Territory-009 + Territory-011 + Territory-013 + Territory-014 + Territory-015 + Territory-017 + Territory-018 + Territory-019 + Territory-021 + Territory-029 + Territory-030 + Territory-034 + Territory-035 + Territory-039 + Territory-053 + Territory-054 + Territory-057 + Territory-061 + Territory-142 + Territory-143 + Territory-145 + Territory-150 + Territory-151 + Territory-154 + Territory-155 + Territory-202 + Territory-419 - verify something - Territory-001 + verify them + Territory-001 + diff --git a/tools/cldr-code/src/main/java/org/unicode/cldr/test/CheckCLDR.java b/tools/cldr-code/src/main/java/org/unicode/cldr/test/CheckCLDR.java index 2e75cf38633..d98b42a0a94 100644 --- a/tools/cldr-code/src/main/java/org/unicode/cldr/test/CheckCLDR.java +++ b/tools/cldr-code/src/main/java/org/unicode/cldr/test/CheckCLDR.java @@ -160,6 +160,11 @@ public static Phase forString(String value) { return result != null ? result : Phase.valueOf(value); } + /** true if it's a 'unit test' phase. */ + public boolean isUnitTest() { + return this == BUILD || this == FINAL_TESTING; + } + /** * Return whether or not to show a row, and if so, how. * @@ -199,7 +204,7 @@ public StatusAction getShowRowAction( } // always forbid bulk import except in data submission. - if (inputMethod == InputMethod.BULK && this != Phase.SUBMISSION) { + if (inputMethod == InputMethod.BULK && (this != Phase.SUBMISSION && isUnitTest())) { return StatusAction.FORBID_UNLESS_DATA_SUBMISSION; } @@ -222,7 +227,7 @@ public StatusAction getShowRowAction( } } - if (this == Phase.SUBMISSION) { + if (this == Phase.SUBMISSION || isUnitTest()) { return (ph.canReadAndWrite()) ? StatusAction.ALLOW : StatusAction.ALLOW_VOTING_AND_TICKET; @@ -288,7 +293,7 @@ public StatusAction getAcceptNewItemAction( } // Allow items if submission - if (this == Phase.SUBMISSION) { + if (this == Phase.SUBMISSION || isUnitTest()) { return StatusAction.ALLOW; }