下面列出了org.junit.jupiter.api.extension.ExtendWith#org.junit.jupiter.api.TestTemplate 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@TestTemplate
public void testCookieRenewOnPost() throws Exception {
mockWebServer.enqueue(OK_COOKIE);
mockWebServer.enqueue(new MockResponse().setResponseCode(403).setBody
("{\"error\":\"credentials_expired\", \"reason\":\"Session expired\"}\r\n"));
mockWebServer.enqueue(OK_COOKIE);
mockWebServer.enqueue(new MockResponse());
CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer)
.username("a")
.password("b")
.build();
HttpConnection request = Http.POST(mockWebServer.url("/").url(), "application/json");
request.setRequestBody("{\"some\": \"json\"}");
HttpConnection response = c.executeRequest(request);
String responseStr = response.responseAsString();
assertTrue(responseStr.isEmpty(), "There should be no response body on the mock response");
response.getConnection().getResponseCode();
}
/**
* Test that the default maximum number of retries is reached and the backoff is of at least the
* expected duration.
*
* @throws Exception
*/
@TestTemplate
public void test429BackoffMaxDefault() throws Exception {
// Always respond 429 for this test
mockWebServer.setDispatcher(MockWebServerResources.ALL_429);
TestTimer t = TestTimer.startTimer();
try {
CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer)
.interceptors(Replay429Interceptor.WITH_DEFAULTS)
.build();
String response = c.executeRequest(Http.GET(c.getBaseUri())).responseAsString();
fail("There should be a TooManyRequestsException instead had response " + response);
} catch (TooManyRequestsException e) {
long duration = t.stopTimer(TimeUnit.MILLISECONDS);
// 3 backoff periods for 4 attempts: 250 + 500 + 1000 = 1750 ms
assertTrue(duration >=
1750, "The duration should be at least 1750 ms, but was " + duration);
assertEquals(4, mockWebServer
.getRequestCount(), "There should be 4 request attempts");
}
}
@WithAccessId(user = "user-1-1")
@WithAccessId(user = "taskadmin")
@TestTemplate
void should_ThrowException_When_UserIsNotAdminOrBusinessAdmin() {
final WorkbasketService workbasketService = taskanaEngine.getWorkbasketService();
WorkbasketAccessItem workbasketAccessItem =
workbasketService.newWorkbasketAccessItem(
"WBI:100000000000000000000000000000000008", "newAccessIdForUpdate");
workbasketAccessItem.setPermCustom1(true);
ThrowingCallable updateWorkbasketAccessItemCall =
() -> {
workbasketService.updateWorkbasketAccessItem(workbasketAccessItem);
};
assertThatThrownBy(updateWorkbasketAccessItemCall).isInstanceOf(NotAuthorizedException.class);
}
/**
* Connect to the local simple https server with SSL authentication disabled.
*/
@TestTemplate
public void localSslAuthenticationDisabled() throws Exception {
// Build a client that connects to the mock server with SSL authentication disabled
CloudantClient dbClient = CloudantClientHelper.newMockWebServerClientBuilder(server)
.disableSSLAuthentication()
.build();
// Queue a 200 OK response
server.enqueue(new MockResponse());
// Make an arbitrary connection to the DB.
dbClient.getAllDbs();
// Test is successful if no exception is thrown, so no explicit check is needed.
}
/**
* Repeat the localSSLAuthenticationDisabled, but with the cookie auth enabled.
* This test validates that the SSL settings also get applied to the cookie interceptor.
*/
@TestTemplate
public void localSSLAuthenticationDisabledWithCookieAuth() throws Exception {
// Mock up an OK cookie response then an OK response for the getAllDbs()
server.enqueue(MockWebServerResources.OK_COOKIE);
server.enqueue(new MockResponse()); //OK 200
// Use a username and password to enable the cookie auth interceptor
CloudantClient dbClient = CloudantClientHelper.newMockWebServerClientBuilder(server)
.username("user")
.password("password")
.disableSSLAuthentication()
.build();
dbClient.getAllDbs();
}
@WithAccessId(user = "admin")
@WithAccessId(user = "taskadmin")
@TestTemplate
void should_ForceCompleteTask_When_NoExplicitPermissionsButUserIsInAdministrativeRole()
throws TaskNotFoundException, InvalidStateException, InvalidOwnerException,
NotAuthorizedException, SQLException {
resetDb(false);
assertThat(TASK_SERVICE.getTask("TKI:000000000000000000000000000000000000").getState())
.isEqualTo(TaskState.CLAIMED);
Task completedTask = TASK_SERVICE.forceCompleteTask("TKI:000000000000000000000000000000000000");
assertThat(completedTask).isNotNull();
assertThat(completedTask.getCompleted()).isNotNull();
assertThat(completedTask.getState()).isEqualTo(TaskState.COMPLETED);
assertThat(completedTask.getModified()).isNotEqualTo(completedTask.getCreated());
}
@WithAccessId(user = "admin")
@WithAccessId(user = "taskadmin")
@TestTemplate
void should_TerminateTask_When_TaskStateIsClaimed()
throws NotAuthorizedException, TaskNotFoundException, InvalidStateException {
List<TaskSummary> taskSummaries =
taskService.createTaskQuery().stateIn(TaskState.CLAIMED).list();
assertThat(taskSummaries.size()).isEqualTo(20);
long numTasksTerminated = taskService.createTaskQuery().stateIn(TaskState.TERMINATED).count();
assertThat(numTasksTerminated).isEqualTo(5);
taskService.terminateTask(taskSummaries.get(0).getId());
long numTasksClaimed = taskService.createTaskQuery().stateIn(TaskState.CLAIMED).count();
assertThat(numTasksClaimed).isEqualTo(19);
numTasksTerminated = taskService.createTaskQuery().stateIn(TaskState.TERMINATED).count();
assertThat(numTasksTerminated).isEqualTo(6);
}
@TestTemplate
public void test429IgnoreRetryAfter() throws Exception {
mockWebServer.enqueue(MockWebServerResources.get429().addHeader("Retry-After", "1"));
mockWebServer.enqueue(new MockResponse());
TestTimer t = TestTimer.startTimer();
CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer)
.interceptors(new Replay429Interceptor(1, 1, false))
.build();
String response = c.executeRequest(Http.GET(c.getBaseUri())).responseAsString();
assertTrue(response.isEmpty(), "There should be no response body on the mock response");
long duration = t.stopTimer(TimeUnit.MILLISECONDS);
assertTrue(duration <
1000, "The duration should be less than 1000 ms, but was " + duration);
assertEquals(2, mockWebServer
.getRequestCount(), "There should be 2 request attempts");
}
/**
* Test that cookie authentication throws a CouchDbException if the credentials were bad.
*
* @throws Exception
*/
@TestTemplate
public void badCredsCookieThrows() {
mockWebServer.enqueue(new MockResponse().setResponseCode(401));
CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer)
.username("bad")
.password("worse")
.build();
CouchDbException re =
assertThrows(CouchDbException.class,
() -> c.executeRequest(Http.GET(c.getBaseUri())).responseAsString(),
"Bad credentials should throw a CouchDbException.");
assertTrue(re.getMessage().startsWith("401 Credentials are incorrect for server"), "The " +
"exception should have been for bad creds.");
}
/**
* Connect to the local simple https server with SSL authentication enabled explicitly.
* This should throw an exception because the SSL authentication fails.
*/
@TestTemplate
public void localSslAuthenticationEnabled() throws Exception {
CouchDbException thrownException = null;
try {
CloudantClient dbClient = CloudantClientHelper.newMockWebServerClientBuilder(server)
.build();
// Queue a 200 OK response
server.enqueue(new MockResponse());
// Make an arbitrary connection to the DB.
dbClient.getAllDbs();
} catch (CouchDbException e) {
thrownException = e;
}
validateClientAuthenticationException(thrownException);
}
@TestTemplate
public void testReadBeforeExecute() throws Exception {
HttpConnection conn = new HttpConnection("POST", new URL(dbResource.getDbURIWithUserInfo()),
"application/json");
ByteArrayInputStream bis = new ByteArrayInputStream(data.getBytes());
// nothing read from stream
assertEquals(data.getBytes().length, bis.available());
conn.setRequestBody(bis);
try {
String response = conn.responseAsString();
fail("IOException not thrown as expected instead had response " + response);
} catch (IOException ioe) {
; // "Attempted to read response from server before calling execute()"
}
// stream was not read because execute() was not called
assertEquals(data.getBytes().length, bis.available());
}
/**
* Test the global number of retries
*
* @throws Exception
*/
@TestTemplate
public void testHttpConnectionRetries() throws Exception {
// Just return 200 OK
mockWebServer.setDispatcher(new MockWebServerResources.ConstantResponseDispatcher(200));
CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer)
.interceptors(new HttpConnectionResponseInterceptor() {
@Override
public HttpConnectionInterceptorContext interceptResponse
(HttpConnectionInterceptorContext context) {
// At least do something with the connection, otherwise we risk breaking it
try {
context.connection.getConnection().getResponseCode();
} catch (IOException e) {
fail("IOException getting response code");
}
// Set to always replay
context.replayRequest = true;
return context;
}
})
.build();
String response = c.executeRequest(Http.GET(c.getBaseUri()).setNumberOfRetries(5))
.responseAsString();
assertTrue(response.isEmpty(), "There should be no response body on the mock response");
assertEquals(5, mockWebServer
.getRequestCount(), "There should be 5 request attempts");
}
@TestTemplate
@ExtendWith(ErrorInvocationContextProvider.class)
void error(Class clazz, Message message, String... options) throws Exception {
addOption(options);
addProcessor(new ExternalDomainProcessor());
addCompilationUnit(clazz);
compile();
assertFalse(getCompiledResult());
assertMessage(message);
}
@TestTemplate
public void buildVeryEscapedUri(String path) throws Exception {
URI expected = new URI(uriBase + "/[email protected]%23%25$%23)KLDfdffdg%C3%A9/%[email protected]%23%25$%23)" +
"DFGKLDfdffdg%C3%A9%2Fpath2?detail=/[email protected]%23%25$%23)%C3%A9&revs=%5B1-2%5D");
Map<String, Object> options = new TreeMap<String, Object>();
options.put("revs", "[1-2]");
options.put("detail", "/[email protected]#%$#)\u00E9");
URI actual = helper(path + "/[email protected]#%$#)KLDfdffdg\u00E9").documentId("/[email protected]#%$#)"
+ "DFGKLDfdffdg\u00E9/path2").query(options).build();
Assertions.assertEquals(expected.toASCIIString(), actual.toASCIIString());
}
@TestTemplate
@ExtendWith(ErrorInvocationContextProvider.class)
void error(Class clazz, Message message) throws Exception {
addProcessor(new DaoProcessor());
addCompilationUnit(clazz);
compile();
assertFalse(getCompiledResult());
assertMessage(message);
}
/**
* Check that we can page through a view where we use start and end keys.
* Assert that we don't exceed the limits of those keys.
*/
@TestTemplate
public void startAndEndKeyLimits(CheckPagination.Type type,
boolean descending,
boolean stateless) throws Exception {
startAndEndKeyLimits(type, descending, stateless, true);
}
@TestTemplate
public void inputStreamRetryString() throws Exception {
HttpConnection request = Http.POST(mockWebServer.url("/").url(), "application/json");
String content = "abcde";
request.setRequestBody(content);
testInputStreamRetry(request, content.getBytes("UTF-8"));
}
/**
* Same as {@link #handleNonExpiry403()} but with no reason property in the JSON.
*
* @throws Exception
*/
@TestTemplate
public void handleNonExpiry403NoReason() throws Exception {
// Test for a non-expiry 403, expect 2 requests
basic403Test("403_not_expired_test", null, 2);
}
@WithAccessId(user = "user-1-1")
@WithAccessId(user = "taskadmin")
@TestTemplate
void should_ThrowException_When_UserRoleIsNotAdminOrBusinessAdmin()
throws NotAuthorizedException, WorkbasketNotFoundException {
WorkbasketService workbasketService = taskanaEngine.getWorkbasketService();
Workbasket workbasket = workbasketService.getWorkbasket("USER-1-1", "DOMAIN_A");
workbasket.setName("new name");
assertThatThrownBy(() -> workbasketService.updateWorkbasket(workbasket))
.isInstanceOf(NotAuthorizedException.class);
}
@WithAccessId(user = "user-1-1")
@WithAccessId(user = "taskadmin")
@TestTemplate
void should_ThrowException_When_UserRoleIsNotAdminOrBusinessAdmin() {
WorkbasketService workbasketService = taskanaEngine.getWorkbasketService();
Workbasket workbasket = workbasketService.newWorkbasket("key3", "DOMAIN_A");
workbasket.setName("Megabasket");
workbasket.setType(WorkbasketType.GROUP);
workbasket.setOrgLevel1("company");
ThrowingCallable call = () -> workbasketService.createWorkbasket(workbasket);
assertThatThrownBy(call).isInstanceOf(NotAuthorizedException.class);
}
@WithAccessId(user = "admin")
@WithAccessId(user = "businessadmin")
@WithAccessId(user = "taskadmin")
@TestTemplate
void should_ReturnWorkbasketByKeyAndDomain_When_NoExplicitPermissionButUserHasAdministrativeRole()
throws NotAuthorizedException, WorkbasketNotFoundException {
WorkbasketService workbasketService = taskanaEngine.getWorkbasketService();
Workbasket retrievedWorkbasket =
workbasketService.getWorkbasket("WBI:100000000000000000000000000000000007");
assertThat(retrievedWorkbasket).isNotNull();
assertThat(retrievedWorkbasket.getOwner()).isEqualTo("Peter Maier");
}
@WithAccessId(user = "admin")
@WithAccessId(user = "businessadmin")
@WithAccessId(user = "taskadmin")
@TestTemplate
void should_ReturnWorkbasketById_When_NoExplicitPermissionsButUserIsInAdministrativeRole()
throws NotAuthorizedException, WorkbasketNotFoundException {
WorkbasketService workbasketService = taskanaEngine.getWorkbasketService();
Workbasket retrievedWorkbasket = workbasketService.getWorkbasket("USER-1-2", "DOMAIN_A");
assertThat(retrievedWorkbasket.getOwner()).isEqualTo("Peter Maier");
assertThat(retrievedWorkbasket).isNotNull();
}
@WithAccessId(user = "user-1-1")
@WithAccessId(user = "taskadmin")
@TestTemplate
void should_ThrowException_When_UserRoleIsNotAdminOrBusinessAdmin() {
final WorkbasketService workbasketService = taskanaEngine.getWorkbasketService();
ThrowingCallable retrieveWorkbasketAccessItemCall =
() -> {
workbasketService.getWorkbasketAccessItems("WBI:100000000000000000000000000000000008");
};
assertThatThrownBy(retrieveWorkbasketAccessItemCall).isInstanceOf(NotAuthorizedException.class);
}
@WithAccessId(user = "taskadmin")
@WithAccessId(user = "user-1-1")
@TestTemplate
void should_ThrowException_When_UserRoleIsNotAdminOrBusinessAdmin() {
ClassificationImpl classification =
(ClassificationImpl) classificationService.newClassification("newKey718", "", "TASK");
ThrowingCallable createClassificationCall =
() -> {
classificationService.createClassification(classification);
};
assertThatThrownBy(createClassificationCall).isInstanceOf(NotAuthorizedException.class);
}
@TestTemplate
public void _localDocumentURI(String path) throws Exception {
final String expected = uriBase + "/db_name/_local/mylocaldoc";
DatabaseURIHelper helper = helper(path + "/db_name");
URI localDoc = helper.documentUri("_local/mylocaldoc");
Assertions.assertEquals(expected, localDoc.toString());
}
/**
* Test that if a cookie is expired it does not cause a replay cycle. That is we should not
* retrieve an expired cookie from the store, so a new session request should be made before
* any subsequent request.
*
* @throws Exception
*/
@TestTemplate
public void testNewCookieRequestMadeAfterExpiry(boolean okUsable, String sessionPath) throws
Exception {
// Cookie lifetime in seconds
// As per https://tools.ietf.org/html/rfc6265#section-5.1.1 cookie-date uses an hms time
// This means the granularity of an expires time is 1 second. Assuming a system time of
// hh:mm:00.998, a cookie lifetime of 1 second gives hh:mm:01.998, but if this is truncated
// to hh:mm:01 then the actual lifetime of the cookie is a mere 2 ms.
// Further the calculation of expiry is subject to similar 1 second granularity truncations.
// As such the two rounding effects each could cost up to ~1 second of time. In practice
// this means that a lifetime of less than 3 seconds, whilst desirable for a shorter test
// could result in an impractical amount of time for the two requests
// (_session and subsequent GET) to take place before the cookie expires.
// Effectively we need to allow at least 1 second for each possible truncation, plus 1
// second for the test to take place.
long cookieLifetime = 3L; // TLDR >= 3
// Make a GET request and get a cookie valid for the lifetime declared above
executeTest(okUsable, sessionPath, cookieLifetime,
MockWebServerResources.EXPECTED_OK_COOKIE);
// Sleep for the cookie lifetime, we don't need to add any extra time because the execution
// time of the first request and its preceding session request will have elapsed extra time
// already.
TimeUnit.SECONDS.sleep(cookieLifetime);
// Since the Cookie is expired it should follow the same sequence of POST /_session GET /
// If the expired Cookie was retrieved it would only do GET / and the test would fail.
executeTest(okUsable, sessionPath, null, MockWebServerResources.EXPECTED_OK_COOKIE_2);
}
@TestTemplate
public void buildDocumentUri_options_hasPlus(String path) throws Exception {
URI expected = new URI(uriBase + "/test/path1%2Fpath2?q=class:mammal%2Bwith%2Bplusses");
TreeMap<String, Object> options = new TreeMap<String, Object>();
options.put("q", "class:mammal+with+plusses");
URI actual = helper(path + "/test").documentId("path1/path2").query(options).build();
Assertions.assertEquals(expected, actual);
}
@WithAccessId(user = "admin")
@WithAccessId(user = "taskadmin")
@TestTemplate
void should_ReturnTask_When_NoExplicitPermissionsButUserIsInAdministrativeRole()
throws NotAuthorizedException, TaskNotFoundException {
TaskService taskService = taskanaEngine.getTaskService();
Task task = taskService.getTask("TKI:000000000000000000000000000000000000");
assertThat(task).isNotNull();
}
@TestTemplate
public void buildDocumentUri_options_encodeSeparators(String path) throws Exception {
URI expected = new URI(uriBase +
"/test/path1%2Fpath2?d%26etail%3D=%26%3D%3Dds%26&revs=%5B1-2%5D");
TreeMap<String, Object> options = new TreeMap<String, Object>();
options.put("revs", "[1-2]");
options.put("d&etail=", "&==ds&");
URI actual = helper(path + "/test").documentId("path1/path2").query(options).build();
Assertions.assertEquals(expected, actual);
}
/**
* Check that we can page through a view where the number of results
* is an exact multiple of the number of pages. Check each page contains the documents
* we expect.
*
* Page part way forward, and part way back a few times before paging to the last page.
*/
@TestTemplate
public void partWayInEachDirection(CheckPagination.Type type,
boolean descending,
boolean stateless) throws Exception {
CheckPagination.newTest(type)
.descending(descending)
.docCount(30)
.docsPerPage(5)
.pageToPages(4, 2, 5, 3, 4, 2, 6)
.stateless(stateless)
.runTest(db);
}