Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ public void upgradeDatabase(boolean runScripts) throws StartupException {

log.info("Database is old, beginning upgrade to version "+myVersion);

boolean schemaChangesRequired = dbversion < 610;

// iterate through each upgrade as needed
// to add to the upgrade sequence simply add a new "if" statement
// for whatever version needed and then define a new method upgradeXXX()
Expand Down Expand Up @@ -254,6 +256,10 @@ public void upgradeDatabase(boolean runScripts) throws StartupException {
// make sure the database version is the exact version
// we are upgrading too.
updateDatabaseVersion(con, myVersion);
if (!schemaChangesRequired) {
successMessage("No table changes were required.");
}
successMessage("Database version updated to " + myVersion + ".");
Comment on lines 229 to +262

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably ok for now but this is also a bit brittle.

I think this pattern would be more future proof.

    boolean upgraded = false;

    if(dbversion < xx) {
        upgradeTo...()
        dbversion = yy;
        upgraded = true;
    }
    (...)

   if (!upgraded) { extraMessage(); }

But this can be tweaked for the next release.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gh didn't select the full span, the brittle part is L229 boolean schemaChangesRequired = dbversion < 610;.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — adopted your flag pattern in #184: a schemaUpgraded flag set inside each upgrade block, so the "no table changes" message no longer depends on the hardcoded 610. It's behavior-preserving (at that point dbversion < 610 is true exactly when a block runs), and I added a test for the schema-change path. Folding it into 6.1.6.


} catch (SQLException e) {
throw new StartupException("ERROR obtaining connection");
Expand Down Expand Up @@ -847,7 +853,8 @@ private int getDatabaseVersion() throws StartupException {
}


private int parseVersionString(String vstring) {
// package-private so tests can parse versions exactly as the installer does
static int parseVersionString(String vstring) {
int myversion = 0;

// NOTE: this assumes a maximum of 3 digits for the version number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
throws IOException, ServletException {

HttpServletRequest httpReq = (HttpServletRequest) request;
httpReq.getSession(true);
RollerSession rollerSession = RollerSession.getRollerSession(httpReq);
if (rollerSession != null) {
String userId = rollerSession.getAuthenticatedUser() != null ? rollerSession.getAuthenticatedUser().getId() : "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ public class Install extends UIAction {
private String databaseName = "Unknown";


@Override
public void setPageTitle(String pageTitle) {
this.pageTitle = pageTitle;
}

public String getRootCauseExceptionName() {
return rootCauseException == null ? "" : rootCauseException.getClass().getName();
}

@Override
public boolean isUserRequired() {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ public String getPreviewURL() {
.getUrlStrategy()
.getPreviewURLStrategy(null)
.getWeblogEntryURL(getActionWeblog(), null,
getEntry().getAnchor(), true);
getEntry().getAnchor(), false);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/webapp/WEB-INF/jsps/core/DatabaseError.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

<p>
<s:text name="installer.aboutTheException" />
[<s:property value="getRootCauseException().getClass().getName()" />]
[<s:property value="rootCauseExceptionName" />]
</p>

<p><s:text name="installer.heresTheStackTrace" /></p>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0.
*/
package org.apache.roller.weblogger.business.startup;

import java.sql.*;
import java.util.Properties;
import org.apache.roller.weblogger.business.DatabaseProvider;
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;

class DatabaseInstallerUpgradeTest {
@Test
void versionOnlyUpgradeReportsCompletion() throws Exception {
DatabaseProvider db = mock(DatabaseProvider.class);
DatabaseScriptProvider scripts = mock(DatabaseScriptProvider.class);
Connection con = mock(Connection.class);
Statement query = mock(Statement.class);
ResultSet rows = mock(ResultSet.class);
PreparedStatement update = mock(PreparedStatement.class);
when(db.getConnection()).thenReturn(con);
when(con.createStatement()).thenReturn(query);
when(query.executeQuery(anyString())).thenReturn(rows);
when(rows.next()).thenReturn(true);
when(rows.getString(1)).thenReturn("610");
when(con.prepareStatement(anyString())).thenReturn(update);
DatabaseInstaller installer = new DatabaseInstaller(db, scripts);

// the version the installer writes is the one it reads from
// /roller-version.properties, so derive the expectation from the
// same source and parser instead of pinning a release constant
Properties props = new Properties();
props.load(getClass().getResourceAsStream("/roller-version.properties"));
int expectedVersion = DatabaseInstaller.parseVersionString(props.getProperty("ro.version", "UNKNOWN"));

installer.upgradeDatabase(true);
verify(update).setString(1, String.valueOf(expectedVersion));
verify(update).executeUpdate();
verifyNoInteractions(scripts);
assertTrue(installer.getMessages().stream().anyMatch(m -> m.contains("No table changes were required.")));
assertTrue(installer.getMessages().stream().anyMatch(m -> m.contains("Database version updated to " + expectedVersion + ".")));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,41 @@ public void testDoFilterWithNullRollerSession() throws Exception {
}
}

@Test
void firstFormHasAUsableSalt() throws Exception {
javax.servlet.http.HttpSession session = mock(javax.servlet.http.HttpSession.class);
java.util.Map<String, Object> attributes = new java.util.HashMap<>();
java.util.Map<String, Object> sessionAttributes = new java.util.HashMap<>();
when(request.getSession(true)).thenAnswer(invocation -> {
when(request.getSession(false)).thenReturn(session);
return session;
});
when(session.getAttribute(anyString())).thenAnswer(i -> sessionAttributes.get(i.getArgument(0)));
doAnswer(i -> { sessionAttributes.put(i.getArgument(0), i.getArgument(1)); return null; })
.when(session).setAttribute(anyString(), any());
doAnswer(i -> { attributes.put(i.getArgument(0), i.getArgument(1)); return null; })
.when(request).setAttribute(anyString(), any());
java.util.Map<String, String> salts = new java.util.HashMap<>();
try (MockedStatic<SaltCache> cache = mockStatic(SaltCache.class)) {
cache.when(SaltCache::getInstance).thenReturn(saltCache);
doAnswer(i -> { salts.put(i.getArgument(0), i.getArgument(1)); return null; })
.when(saltCache).put(anyString(), anyString());
when(saltCache.get(anyString())).thenAnswer(i -> salts.get(i.getArgument(0)));
doAnswer(i -> { salts.remove(i.getArgument(0)); return null; })
.when(saltCache).remove(anyString());
filter.doFilter(request, response, chain);
String salt = (String) attributes.get("salt");
org.junit.jupiter.api.Assertions.assertNotNull(salt);
when(request.getParameter("salt")).thenReturn(null);
org.junit.jupiter.api.Assertions.assertFalse(SaltValidator.consumeSubmittedSalt(request));
when(request.getParameter("salt")).thenReturn("unknown");
org.junit.jupiter.api.Assertions.assertFalse(SaltValidator.consumeSubmittedSalt(request));
when(request.getParameter("salt")).thenReturn(salt);
org.junit.jupiter.api.Assertions.assertTrue(SaltValidator.consumeSubmittedSalt(request));
org.junit.jupiter.api.Assertions.assertFalse(SaltValidator.consumeSubmittedSalt(request));
}
}

private static class TestUser extends User {
private final String id;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0.
*/
package org.apache.roller.weblogger.ui.struts2.core;

import org.apache.roller.weblogger.business.WebloggerFactory;
import org.apache.roller.weblogger.business.startup.*;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;

class InstallTest {
@Test
void installerExposesItsTitleAndExceptionName() {
Install action = spy(new Install());
doAnswer(i -> i.getArgument(0)).when(action).getText(anyString());
assertEquals("", action.getRootCauseExceptionName());
try (MockedStatic<WebloggerFactory> factory = mockStatic(WebloggerFactory.class);
MockedStatic<WebloggerStartup> startup = mockStatic(WebloggerStartup.class)) {
startup.when(WebloggerStartup::getDatabaseProviderException)
.thenReturn(new StartupException("Connection failed", new IllegalStateException("offline")));
assertEquals("database_error", action.execute());
assertEquals("installer.error.connection.pageTitle", action.getPageTitle());
assertEquals("java.lang.IllegalStateException", action.getRootCauseExceptionName());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0.
*/
package org.apache.roller.weblogger.ui.struts2.editor;

import java.net.URI;
import org.apache.roller.weblogger.business.*;
import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
import org.apache.roller.weblogger.pojos.*;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;

class EntryEditPreviewTest {
@Test
void previewUsesTheEditorsOrigin() {
Weblogger weblogger = mock(Weblogger.class);
when(weblogger.getUrlStrategy()).thenReturn(new MultiWeblogURLStrategy());
try (MockedStatic<WebloggerFactory> factory = mockStatic(WebloggerFactory.class);
MockedStatic<WebloggerRuntimeConfig> config = mockStatic(WebloggerRuntimeConfig.class)) {
factory.when(WebloggerFactory::getWeblogger).thenReturn(weblogger);
config.when(WebloggerRuntimeConfig::getAbsoluteContextURL).thenReturn("http://other.example/roller");
Weblog weblog = new Weblog();
weblog.setHandle("mainpage");
WeblogEntry entry = new WeblogEntry();
entry.setAnchor("test entry");
EntryEdit action = new EntryEdit();
action.setActionWeblog(weblog);
action.setEntry(entry);
for (String context : new String[]{"", "/roller"}) {
config.when(WebloggerRuntimeConfig::getRelativeContextURL).thenReturn(context);
String preview = action.getPreviewURL();
assertEquals(context + "/roller-ui/authoring/preview/mainpage/?previewEntry=test+entry", preview);
for (String scheme : new String[]{"http", "https"}) {
URI editor = URI.create(scheme + "://example.org:8443" + context + "/roller-ui/authoring/entryEdit.rol");
URI target = editor.resolve(preview);
assertEquals(editor.getScheme(), target.getScheme());
assertEquals(editor.getAuthority(), target.getAuthority());
}
}
}
}
}
Loading