Merge pull request #23 from Kingsrook/dev

refresh querystats from dev
This commit is contained in:
2023-06-22 19:07:15 -05:00
committed by GitHub
87 changed files with 6582 additions and 224 deletions

View File

@ -26,6 +26,7 @@ import com.kingsrook.qqq.backend.core.context.QContext;
import com.kingsrook.qqq.backend.core.logging.QLogger;
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
import com.kingsrook.qqq.backend.core.model.session.QSession;
import com.kingsrook.qqq.backend.core.model.session.QUser;
import com.kingsrook.qqq.backend.core.modules.backend.implementations.memory.MemoryRecordStore;
import com.kingsrook.qqq.backend.core.utils.TestUtils;
import org.junit.jupiter.api.AfterEach;
@ -47,7 +48,10 @@ public class BaseTest
@BeforeEach
void baseBeforeEach()
{
QContext.init(TestUtils.defineInstance(), new QSession());
QContext.init(TestUtils.defineInstance(), new QSession()
.withUser(new QUser()
.withIdReference("001")
.withFullName("Anonymous")));
resetMemoryRecordStore();
}

View File

@ -197,6 +197,16 @@ class QInstanceEnricherTest extends BaseTest
assertEquals("Something USA", QInstanceEnricher.nameToLabel("somethingUSA"));
assertEquals("Number 1 Dad", QInstanceEnricher.nameToLabel("number1Dad"));
assertEquals("Number 417 Dad", QInstanceEnricher.nameToLabel("number417Dad"));
assertEquals("Default Wms System Id", QInstanceEnricher.nameToLabel("defaultWmsSystemId"));
QInstanceEnricher.addLabelMapping("\\bWms\\b", "WMS");
assertEquals("Default WMS System Id", QInstanceEnricher.nameToLabel("defaultWmsSystemId"));
QInstanceEnricher.clearLabelMappings();
assertEquals("Api Client Id", QInstanceEnricher.nameToLabel("apiClientId"));
QInstanceEnricher.addLabelMapping("\\bApi\\b", "API");
assertEquals("API Client Id", QInstanceEnricher.nameToLabel("apiClientId"));
QInstanceEnricher.clearLabelMappings();
}

View File

@ -0,0 +1,190 @@
/*
* QQQ - Low-code Application Framework for Engineers.
* Copyright (C) 2021-2023. Kingsrook, LLC
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
* contact@kingsrook.com
* https://github.com/Kingsrook/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.kingsrook.qqq.backend.core.logging;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.kingsrook.qqq.backend.core.BaseTest;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Core;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.filter.LevelRangeFilter;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/*******************************************************************************
** Unit test for com.kingsrook.qqq.backend.core.logging.QLogger
**
*******************************************************************************/
@Disabled // disabled because could never get the custom appender class to receive logEvents that have their levels set (always null)
class QLoggerTest extends BaseTest
{
private static final QLogger LOG = QLogger.getLogger(QLoggerTest.class);
private static final ListAppender listAppender = ListAppender.createAppender();
/*******************************************************************************
**
*******************************************************************************/
@BeforeEach
void beforeAll() throws Exception
{
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testDowngradingWarnings() throws Exception
{
org.apache.logging.log4j.core.Logger logger = (org.apache.logging.log4j.core.Logger) LogManager.getLogger(QLoggerTest.class);
logger.addAppender(listAppender);
listAppender.start();
try
{
try
{
try
{
try
{
throw (new QException("Some deepest exception..."));
}
catch(Exception e)
{
String warning = "Less deep warning";
LOG.warn(warning, e);
throw (new QException(warning, e));
}
}
catch(Exception e2)
{
String warning = "Middle warning";
LOG.warn(warning, e2);
throw (new QException(warning, e2));
}
}
catch(Exception e2)
{
String warning = "Last warning";
LOG.warn(warning, e2);
throw (new QException(warning, e2));
}
}
catch(Exception e3)
{
/////////////////////////
// check results below //
/////////////////////////
}
assertThat(listAppender.getEventList()).isNotNull();
assertThat(listAppender.getEventList().size()).isEqualTo(5);
int counter = 0;
for(LogEvent logEvent : listAppender.getEventList())
{
if(counter == 0)
{
assertThat(logEvent.getLevel()).isEqualTo(Level.WARN);
}
else
{
assertThat(logEvent.getLevel()).isEqualTo(Level.INFO);
}
counter++;
}
}
/*******************************************************************************
** appender to add to logger to keep a list of log events
*******************************************************************************/
@Plugin(name = "ListAppender", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE)
public static class ListAppender extends AbstractAppender
{
private List<LogEvent> eventList = new ArrayList<>();
/*******************************************************************************
**
*******************************************************************************/
protected ListAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout, final boolean ignoreExceptions, final Property[] properties)
{
super(name, filter, layout, ignoreExceptions, properties);
}
/*******************************************************************************
**
*******************************************************************************/
@PluginFactory
public static ListAppender createAppender()
{
LevelRangeFilter levelRangeFilter = LevelRangeFilter.createFilter(Level.TRACE, Level.ERROR, Filter.Result.ACCEPT, Filter.Result.ACCEPT);
// return (new ListAppender("ListApppender", levelRangeFilter, null, true, null));
return (new ListAppender("ListApppender", null, null, true, null));
}
/*******************************************************************************
**
*******************************************************************************/
@Override
public void append(LogEvent event)
{
eventList.add(event);
}
/*******************************************************************************
** Getter for eventList
*******************************************************************************/
public List<LogEvent> getEventList()
{
return (this.eventList);
}
}
}

View File

@ -0,0 +1,143 @@
/*
* QQQ - Low-code Application Framework for Engineers.
* Copyright (C) 2021-2023. Kingsrook, LLC
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
* contact@kingsrook.com
* https://github.com/Kingsrook/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.kingsrook.qqq.backend.core.processes.implementations.savedfilters;
import java.util.List;
import com.kingsrook.qqq.backend.core.BaseTest;
import com.kingsrook.qqq.backend.core.actions.processes.RunProcessAction;
import com.kingsrook.qqq.backend.core.context.QContext;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput;
import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessOutput;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
import com.kingsrook.qqq.backend.core.model.savedfilters.SavedFiltersMetaDataProvider;
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
import com.kingsrook.qqq.backend.core.utils.TestUtils;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
/*******************************************************************************
** Unit test for all saved filter processes
*******************************************************************************/
class SavedFilterProcessTests extends BaseTest
{
/*******************************************************************************
**
*******************************************************************************/
@Test
void test() throws QException
{
QInstance qInstance = QContext.getQInstance();
new SavedFiltersMetaDataProvider().defineAll(qInstance, TestUtils.MEMORY_BACKEND_NAME, null);
String tableName = TestUtils.TABLE_NAME_PERSON_MEMORY;
{
///////////////////////////////////////////
// query - should be no filters to start //
///////////////////////////////////////////
RunProcessInput runProcessInput = new RunProcessInput();
runProcessInput.setProcessName(QuerySavedFilterProcess.getProcessMetaData().getName());
runProcessInput.addValue("tableName", tableName);
RunProcessOutput runProcessOutput = new RunProcessAction().execute(runProcessInput);
assertEquals(0, ((List<?>) runProcessOutput.getValues().get("savedFilterList")).size());
}
Integer savedFilterId;
{
////////////////////////
// store a new filter //
////////////////////////
RunProcessInput runProcessInput = new RunProcessInput();
runProcessInput.setProcessName(StoreSavedFilterProcess.getProcessMetaData().getName());
runProcessInput.addValue("label", "My Filter");
runProcessInput.addValue("tableName", tableName);
runProcessInput.addValue("filterJson", JsonUtils.toJson(new QQueryFilter(new QFilterCriteria("id", QCriteriaOperator.EQUALS, 47))));
RunProcessOutput runProcessOutput = new RunProcessAction().execute(runProcessInput);
List<QRecord> savedFilterList = (List<QRecord>) runProcessOutput.getValues().get("savedFilterList");
assertEquals(1, savedFilterList.size());
savedFilterId = savedFilterList.get(0).getValueInteger("id");
assertNotNull(savedFilterId);
}
{
////////////////////////////////////
// query - should find our filter //
////////////////////////////////////
RunProcessInput runProcessInput = new RunProcessInput();
runProcessInput.setProcessName(QuerySavedFilterProcess.getProcessMetaData().getName());
runProcessInput.addValue("tableName", tableName);
RunProcessOutput runProcessOutput = new RunProcessAction().execute(runProcessInput);
List<QRecord> savedFilterList = (List<QRecord>) runProcessOutput.getValues().get("savedFilterList");
assertEquals(1, savedFilterList.size());
assertEquals(1, savedFilterList.get(0).getValueInteger("id"));
assertEquals("My Filter", savedFilterList.get(0).getValueString("label"));
}
{
///////////////////////
// update our filter //
///////////////////////
RunProcessInput runProcessInput = new RunProcessInput();
runProcessInput.setProcessName(StoreSavedFilterProcess.getProcessMetaData().getName());
runProcessInput.addValue("id", savedFilterId);
runProcessInput.addValue("label", "My Updated Filter");
runProcessInput.addValue("tableName", tableName);
runProcessInput.addValue("filterJson", JsonUtils.toJson(new QQueryFilter(new QFilterCriteria("id", QCriteriaOperator.EQUALS, 47))));
RunProcessOutput runProcessOutput = new RunProcessAction().execute(runProcessInput);
List<QRecord> savedFilterList = (List<QRecord>) runProcessOutput.getValues().get("savedFilterList");
assertEquals(1, savedFilterList.size());
assertEquals(1, savedFilterList.get(0).getValueInteger("id"));
assertEquals("My Updated Filter", savedFilterList.get(0).getValueString("label"));
}
{
///////////////////////
// delete our filter //
///////////////////////
RunProcessInput runProcessInput = new RunProcessInput();
runProcessInput.setProcessName(DeleteSavedFilterProcess.getProcessMetaData().getName());
runProcessInput.addValue("id", savedFilterId);
RunProcessOutput runProcessOutput = new RunProcessAction().execute(runProcessInput);
}
{
////////////////////////////////////////
// query - should be no filters again //
////////////////////////////////////////
RunProcessInput runProcessInput = new RunProcessInput();
runProcessInput.setProcessName(QuerySavedFilterProcess.getProcessMetaData().getName());
runProcessInput.addValue("tableName", tableName);
RunProcessOutput runProcessOutput = new RunProcessAction().execute(runProcessInput);
assertEquals(0, ((List<?>) runProcessOutput.getValues().get("savedFilterList")).size());
}
}
}

View File

@ -26,6 +26,7 @@ import com.kingsrook.qqq.backend.core.BaseTest;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.exceptions.QUserFacingException;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
@ -88,6 +89,33 @@ class ExceptionUtilsTest extends BaseTest
/*******************************************************************************
**
*******************************************************************************/
@Test
void testConcatenateMessagesFromChain()
{
assertNull(ExceptionUtils.concatenateMessagesFromChain(null));
assertEquals("QException", ExceptionUtils.concatenateMessagesFromChain(new QException((String) null)));
assertEquals("QException", ExceptionUtils.concatenateMessagesFromChain(new QException("")));
assertEquals("foo; bar", ExceptionUtils.concatenateMessagesFromChain(new QException("foo", new QException("bar"))));
assertEquals("foo; QException; bar", ExceptionUtils.concatenateMessagesFromChain(new QException("foo", new QException(null, new QException("bar")))));
MyException selfCaused = new MyException("selfCaused");
selfCaused.setCause(selfCaused);
assertEquals("selfCaused", ExceptionUtils.concatenateMessagesFromChain(selfCaused));
MyException cycle1 = new MyException("cycle1");
MyException cycle2 = new MyException("cycle2");
cycle1.setCause(cycle2);
cycle2.setCause(cycle1);
assertEquals("cycle1; cycle2", ExceptionUtils.concatenateMessagesFromChain(cycle1));
assertEquals("cycle2; cycle1", ExceptionUtils.concatenateMessagesFromChain(cycle2));
}
/*******************************************************************************
** Test exception class - lets you set the cause, easier to create a loop.
*******************************************************************************/
@ -97,6 +125,9 @@ class ExceptionUtilsTest extends BaseTest
/*******************************************************************************
**
*******************************************************************************/
public MyException(String message)
{
super(message);
@ -104,6 +135,9 @@ class ExceptionUtilsTest extends BaseTest
/*******************************************************************************
**
*******************************************************************************/
public MyException(Throwable cause)
{
super(cause);
@ -111,6 +145,9 @@ class ExceptionUtilsTest extends BaseTest
/*******************************************************************************
**
*******************************************************************************/
public void setCause(Throwable cause)
{
myCause = cause;

View File

@ -78,7 +78,7 @@ class MapBuilderTest
@Test
void testTypeYouRequest()
{
Map<String, Integer> myTreeMap = MapBuilder.<String, Integer>of(TreeMap::new).with("1", 1).with("2", 2).build();
TreeMap<String, Integer> myTreeMap = MapBuilder.of(() -> new TreeMap<String, Integer>()).with("1", 1).with("2", 2).build();
assertTrue(myTreeMap instanceof TreeMap);
}