-
Notifications
You must be signed in to change notification settings - Fork 467
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#27959 include tests changes in 24.04.24 LTS
- Loading branch information
1 parent
43eecf8
commit ab4ff12
Showing
26 changed files
with
1,380 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
170 changes: 170 additions & 0 deletions
170
dotcms-integration/src/test/java/com/dotcms/ai/viewtool/AIViewToolTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
package com.dotcms.ai.viewtool; | ||
|
||
import com.dotcms.ai.app.AppConfig; | ||
import com.dotcms.datagen.UserDataGen; | ||
import com.dotcms.util.IntegrationTestInitService; | ||
import com.dotcms.util.network.IPUtils; | ||
import com.dotmarketing.util.json.JSONObject; | ||
import com.github.tomakehurst.wiremock.WireMockServer; | ||
import com.liferay.portal.model.User; | ||
import org.apache.velocity.tools.view.context.ViewContext; | ||
import org.junit.AfterClass; | ||
import org.junit.Before; | ||
import org.junit.BeforeClass; | ||
import org.junit.Test; | ||
|
||
import java.io.File; | ||
import java.util.Map; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertFalse; | ||
import static org.junit.Assert.assertNotNull; | ||
import static org.junit.Assert.assertTrue; | ||
import static org.mockito.Mockito.mock; | ||
|
||
/** | ||
* This class tests the functionality of the AIViewTool class. | ||
* It uses a mock server to simulate the OpenAI API and checks the responses of the AIViewTool methods. | ||
* The class follows the Gherkin style for test documentation, with each test method representing a scenario. | ||
* Each scenario is described in terms of "Given", "When", and "Then" steps. | ||
* | ||
* @author vico | ||
*/ | ||
public class AIViewToolTest implements AiTest { | ||
|
||
private static AppConfig config; | ||
private static WireMockServer wireMockServer; | ||
|
||
private User user; | ||
private AIViewTool aiViewTool; | ||
|
||
@BeforeClass | ||
public static void beforeClass() throws Exception { | ||
IntegrationTestInitService.getInstance().init(); | ||
IPUtils.disabledIpPrivateSubnet(true); | ||
wireMockServer = AiTest.prepareWireMock(); | ||
config = AiTest.prepareConfig(wireMockServer); | ||
} | ||
|
||
@AfterClass | ||
public static void afterClass() { | ||
wireMockServer.stop(); | ||
IPUtils.disabledIpPrivateSubnet(false); | ||
} | ||
|
||
@Before | ||
public void setup() { | ||
user = new UserDataGen().nextPersisted(); | ||
aiViewTool = prepareAIViewTool(); | ||
aiViewTool.init(mock(ViewContext.class)); | ||
} | ||
|
||
/** | ||
* Scenario: Generate text from a string prompt | ||
* Given a string prompt about Club Atletico Boca Juniors | ||
* When the generateText method is called with the prompt | ||
* Then the response should contain a text about Club Atletico Boca Juniors | ||
*/ | ||
@Test | ||
public void test_generateText_fromStringPrompt() { | ||
// given | ||
final String prompt = "Short text about Club Atletico Boca Juniors"; | ||
// when | ||
final JSONObject response = aiViewTool.generateText(prompt); | ||
// then | ||
assertTextResponse(response, "Club Atletico Boca Juniors"); | ||
} | ||
|
||
/** | ||
* Scenario: Generate text from a map prompt | ||
* Given a map prompt about Theory of Chaos | ||
* When the generateText method is called with the prompt | ||
* Then the response should contain a text about Theory of Chaos | ||
*/ | ||
@Test | ||
public void test_generateText_fromMapPrompt() { | ||
// given | ||
final Map<String, Object> prompt = Map.of("prompt", "Short text about Theory of Chaos"); | ||
// when | ||
final JSONObject response = aiViewTool.generateText(prompt); | ||
// then | ||
assertTextResponse( | ||
response, | ||
"The Theory of Chaos is a scientific concept that suggests the universe is inherently unpredictable"); | ||
} | ||
|
||
/** | ||
* Scenario: Generate image from a string prompt | ||
* Given a string prompt about Jupiter moon Ganymede | ||
* When the generateImage method is called with the prompt | ||
* Then the response should contain an image about Jupiter moon Ganymede | ||
*/ | ||
@Test | ||
public void test_generateImage_fromStringPrompt() { | ||
// given | ||
final String prompt = "Image about Jupiter moon Ganymede"; | ||
// when | ||
final JSONObject response = aiViewTool.generateImage(prompt); | ||
// then | ||
assertImageResponse(response, prompt, "ganymede"); | ||
} | ||
|
||
/** | ||
* Scenario: Generate image from a map prompt | ||
* Given a map prompt about Dalai Lama winning a slam dunk contest | ||
* When the generateImage method is called with the prompt | ||
* Then the response should contain an image of Dalai Lama winning a slam dunk contest | ||
*/ | ||
@Test | ||
public void test_generateImage_fromMapPrompt() { | ||
// given | ||
final Map<String, Object> prompt = Map.of("prompt", "Image of Dalai Lama winning a slam dunk contest"); | ||
// when | ||
final JSONObject response = aiViewTool.generateImage(prompt); | ||
// then | ||
assertImageResponse(response, prompt.get("prompt").toString(), "dalailama"); | ||
} | ||
|
||
private void assertTextResponse(final JSONObject response, final String containedText) { | ||
assertNotNull(response); | ||
assertTrue(response.containsKey("choices")); | ||
assertFalse(response.getJSONArray("choices").isEmpty()); | ||
assertTrue(response.getJSONArray("choices").getJSONObject(0).containsKey("message")); | ||
assertTrue(response.getJSONArray("choices") | ||
.getJSONObject(0) | ||
.getJSONObject("message") | ||
.containsKey("content")); | ||
assertTrue(response.getJSONArray("choices") | ||
.getJSONObject(0) | ||
.getJSONObject("message") | ||
.getString("content") | ||
.contains(containedText)); | ||
} | ||
|
||
private void assertImageResponse(final JSONObject response, final String prompt, final String path) { | ||
assertNotNull(response); | ||
assertEquals(prompt, response.getString("originalPrompt")); | ||
assertEquals("http://localhost:50505/s/" + path, response.getString("url")); | ||
assertTrue(response.containsKey("tempFileName")); | ||
assertTrue(wasFileSaved(response)); | ||
} | ||
|
||
private boolean wasFileSaved(final JSONObject response) { | ||
return new File(response.getString("tempFile")).exists(); | ||
} | ||
|
||
private AIViewTool prepareAIViewTool() { | ||
return new AIViewTool() { | ||
@Override | ||
User user() { | ||
return user; | ||
} | ||
|
||
@Override | ||
AppConfig config() { | ||
return config; | ||
} | ||
}; | ||
} | ||
|
||
} |
89 changes: 89 additions & 0 deletions
89
dotcms-integration/src/test/java/com/dotcms/ai/viewtool/AiTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package com.dotcms.ai.viewtool; | ||
|
||
import com.dotcms.ai.app.AppConfig; | ||
import com.dotcms.ai.app.AppKeys; | ||
import com.dotcms.security.apps.Secret; | ||
import com.dotcms.security.apps.Type; | ||
import com.dotcms.util.WireMockTestHelper; | ||
import com.github.tomakehurst.wiremock.WireMockServer; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
public interface AiTest { | ||
|
||
String API_URL = "http://localhost:%d/c"; | ||
String API_IMAGE_URL = "http://localhost:%d/i"; | ||
String API_KEY = "some-api-key-1a2bc3"; | ||
String MODEL = "gpt-3.5-turbo-16k"; | ||
String IMAGE_MODEL = "dall-e-3"; | ||
String IMAGE_SIZE = "1024x1024"; | ||
int PORT = 50505; | ||
|
||
static AppConfig prepareConfig(final WireMockServer wireMockServer) { | ||
return new AppConfig(appConfigMap(wireMockServer)); | ||
} | ||
|
||
static AppConfig prepareCompletionConfig(final WireMockServer wireMockServer) { | ||
return new AppConfig(completionAppConfigMap(appConfigMap(wireMockServer))); | ||
} | ||
|
||
static WireMockServer prepareWireMock() { | ||
final WireMockServer wireMockServer = WireMockTestHelper.wireMockServer(PORT); | ||
wireMockServer.start(); | ||
|
||
return wireMockServer; | ||
} | ||
|
||
private static Map<String, Secret> completionAppConfigMap(final Map<String, Secret> configMap) { | ||
final Map<String, Secret> completionValues = Map.of( | ||
AppKeys.COMPLETION_ROLE_PROMPT.key, | ||
Secret.builder() | ||
.withType(Type.STRING) | ||
.withValue(AppKeys.COMPLETION_ROLE_PROMPT.defaultValue.toCharArray()) | ||
.build(), | ||
|
||
AppKeys.COMPLETION_TEXT_PROMPT.key, | ||
Secret.builder() | ||
.withType(Type.STRING) | ||
.withValue(AppKeys.COMPLETION_TEXT_PROMPT.defaultValue.toCharArray()) | ||
.build(), | ||
|
||
AppKeys.MODEL.key, | ||
Secret.builder() | ||
.withType(Type.STRING) | ||
.withValue(AppKeys.MODEL.defaultValue.toCharArray()) | ||
.build() | ||
); | ||
final Map<String, Secret> all = new HashMap<>(configMap); | ||
all.putAll(completionValues); | ||
return Map.copyOf(all); | ||
} | ||
|
||
private static Map<String, Secret> appConfigMap(final WireMockServer wireMockServer) { | ||
return Map.of( | ||
AppKeys.API_URL.key, | ||
Secret.builder() | ||
.withType(Type.STRING) | ||
.withValue(String.format(API_URL, wireMockServer.port()).toCharArray()) | ||
.build(), | ||
|
||
AppKeys.API_IMAGE_URL.key, | ||
Secret.builder() | ||
.withType(Type.STRING) | ||
.withValue(String.format(API_IMAGE_URL, wireMockServer.port()).toCharArray()) | ||
.build(), | ||
|
||
AppKeys.API_KEY.key, | ||
Secret.builder().withType(Type.STRING).withValue(API_KEY.toCharArray()).build(), | ||
|
||
AppKeys.MODEL.key, | ||
Secret.builder().withType(Type.STRING).withValue(MODEL.toCharArray()).build(), | ||
|
||
AppKeys.IMAGE_MODEL.key, | ||
Secret.builder().withType(Type.STRING).withValue(IMAGE_MODEL.toCharArray()).build(), | ||
|
||
AppKeys.IMAGE_SIZE.key, | ||
Secret.builder().withType(Type.SELECT).withValue(IMAGE_SIZE.toCharArray()).build()); | ||
} | ||
} |
Oops, something went wrong.