[Added] Tests and some more functionality to the Services

This commit is contained in:
Ninjaws
2024-10-30 21:47:45 +01:00
parent bf66869ebf
commit 2505fce920
21 changed files with 535 additions and 121 deletions
@@ -1,13 +1,12 @@
package com.ninjaws.quiz;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class QuizApplicationTests {
@Test
void contextLoads() {
}
// @Test
// void contextLoads() {
// }
}
@@ -0,0 +1,21 @@
package com.ninjaws.quiz.scala;
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import scala.concurrent.duration._
class QuestionStatusSimulation extends Simulation {
val httpProtocol = http.baseUrl("http://localhost:9090").acceptHeader("application/json")
val requestQuestions = exec(http("Request Questions").get("/questions/bla").check(status.is(200)).check(jsonPath("$.id").saveAs("sessionId")))
val checkStatus = exec(http("Check Status").get("/status/${sessionId}").check(status.is(200),jsonPath("$.status").notNull))
val scn = scenario("Check Questions Status Completion").exec(requestQuestions).pause(1).asLongAsDuring(session => session("completed").asOption[Boolean].getOrElse(false) == false, 30.seconds) {
exec(checkStatus).pause(1).exec{ session => val status = session("status").asOption[String]
session.set("completed", status.isDefined && status.get != "null")
}
}
setUp(
scn.inject(atOnceUsers(10))
).protocols(httpProtocol);
}
@@ -0,0 +1,114 @@
package com.ninjaws.quiz.services;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ninjaws.quiz.models.QuizSettings;
@SpringBootTest
public class ApiServiceTest {
@Autowired
private ApiService apiService;
@Autowired
private ObjectMapper objectMapper;
/**
* The external API only allows one request every 5 seconds
*/
@AfterEach
public void cooldown() throws InterruptedException {
Thread.sleep(5000);
}
@Test
public void testRequestQuestions() throws Exception {
QuizSettings settings = new QuizSettings();
String jsonResponse = apiService.requestQuestions(settings);
JsonNode jsonNode = objectMapper.readTree(jsonResponse);
// Check if the response code is as expected
assertThat(jsonNode.has("response_code")).isTrue();
assertThat(jsonNode.get("response_code").asInt()).isEqualTo(0);
// Check the results array
assertThat(jsonNode.has("results")).isTrue();
assertThat(jsonNode.get("results").isArray()).isTrue();
assertThat(jsonNode.get("results").size()).isEqualTo(10);
// Verify the first result has the expected fields
JsonNode firstResult = jsonNode.get("results").get(0);
assertThat(firstResult.has("type")).isTrue();
assertThat(firstResult.has("difficulty")).isTrue();
assertThat(firstResult.has("category")).isTrue();
assertThat(firstResult.has("question")).isTrue();
assertThat(firstResult.has("correct_answer")).isTrue();
assertThat(firstResult.has("incorrect_answers")).isTrue();
assertThat(firstResult.get("incorrect_answers").size()).isGreaterThan(0);
}
@Test
public void testAllParams() throws Exception {
int amount = 10;
QuizSettings settings = new QuizSettings();
settings.setAmount(amount);
settings.setCategory(QuizSettings.Category.HISTORY);
settings.setType(QuizSettings.Type.MULTIPLE);
settings.setDifficulty(QuizSettings.Difficulty.MEDIUM);
String jsonResponse = apiService.requestQuestions(settings);
JsonNode jsonNode = objectMapper.readTree(jsonResponse);
// Check if the response code is as expected
assertThat(jsonNode.has("response_code")).isTrue();
assertThat(jsonNode.get("response_code").asInt()).isEqualTo(0);
// Check the results array
assertThat(jsonNode.has("results")).isTrue();
assertThat(jsonNode.get("results").isArray()).isTrue();
assertThat(jsonNode.get("results").size()).isEqualTo(amount);
// Verify the first result has the expected fields
JsonNode firstResult = jsonNode.get("results").get(0);
String retrievedType = firstResult.get("type").toString();
String retrievedDifficulty = firstResult.get("difficulty").toString();
String retrievedCategory = firstResult.get("category").toString();
assertThat(retrievedType.equals(settings.getType().getApiValue()));
assertThat(retrievedDifficulty.equals(settings.getDifficulty().getApiValue()));
assertThat(retrievedCategory.equals("Animals"));
assertThat(firstResult.get("incorrect_answers").size()).isEqualTo(3);
}
/**
* If the API doesn't have the requested amount of questions, it will return an empty list and respond with 1
*/
@Test
public void testCombinationThatResultsInZeroQuestions() throws Exception {
int amount = 30;
QuizSettings settings = new QuizSettings();
settings.setAmount(amount);
settings.setCategory(QuizSettings.Category.ANIMALS);
settings.setType(QuizSettings.Type.MULTIPLE);
settings.setDifficulty(QuizSettings.Difficulty.MEDIUM);
String jsonResponse = apiService.requestQuestions(settings);
JsonNode jsonNode = objectMapper.readTree(jsonResponse);
// Check if the response code is as expected
assertThat(jsonNode.has("response_code")).isTrue();
assertThat(jsonNode.get("response_code").asInt()).isEqualTo(1);
// Check the results array
assertThat(jsonNode.has("results")).isTrue();
assertThat(jsonNode.get("results").isArray()).isTrue();
assertThat(jsonNode.get("results").size()).isEqualTo(0);
}
}
@@ -0,0 +1,73 @@
package com.ninjaws.quiz.services;
import org.junit.jupiter.api.TestInstance;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
// @EnableScheduling
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class QuizServiceTest {
// @InjectMocks
// private QuizService quizService;
// @Mock
// private ApiService apiService;
// @BeforeAll
// public void setUp() {
// MockitoAnnotations.openMocks(this);
// // Cache<String, Session> cache = Caffeine.newBuilder()
// // .expireAfterWrite(1, TimeUnit.HOURS)
// // .build(); // Create a mock cache or a real cache for tests
// // quizService = new QuizService(cache);
// }
// @Test
// public void testCreateSession() {
// QuizSettings settings = new QuizSettings();
// String response = quizService.createSession(settings);
// assertTrue(response instanceof String);
// }
// /**
// * TODO: Fix the test
// * Seems to clear the cache and queue when the createSession is finished
// */
// @Test
// public void testCheckSession() throws InterruptedException {
// QuizSettings settings = new QuizSettings();
// when(apiService.requestQuestions(settings)).thenReturn("{\"response_code\":0,\"results\":[{\"type\":\"multiple\",\"difficulty\":\"hard\",\"category\":\"Entertainment: Video Games\",\"question\":\"The map featured in Arma 3 named &quot;Altis&quot; is based off of what Greek island?\",\"correct_answer\":\"Lemnos\",\"incorrect_answers\":[\"Ithaca\",\"Naxos\",\"Anafi\"]},{\"type\":\"multiple\",\"difficulty\":\"medium\",\"category\":\"Entertainment: Music\",\"question\":\"What is the last song on the first Panic! At the Disco album?\",\"correct_answer\":\"Build God, Then We&#039;ll Talk\",\"incorrect_answers\":[\"Nails for Breakfast, Tacks for Snacks\",\"I Write Sins Not Tragedies\",\"Lying Is The Most Fun A Girl Can Have Without Taking Her Clothes Off\"]},{\"type\":\"multiple\",\"difficulty\":\"easy\",\"category\":\"Entertainment: Video Games\",\"question\":\"Which of these is NOT a playable character in the 2016 video game Overwatch?\",\"correct_answer\":\"Invoker\",\"incorrect_answers\":[\"Mercy\",\"Winston\",\"Zenyatta\"]},{\"type\":\"multiple\",\"difficulty\":\"medium\",\"category\":\"Science: Computers\",\"question\":\"What does AD stand for in relation to Windows Operating Systems? \",\"correct_answer\":\"Active Directory\",\"incorrect_answers\":[\"Alternative Drive\",\"Automated Database\",\"Active Department\"]},{\"type\":\"multiple\",\"difficulty\":\"medium\",\"category\":\"Entertainment: Japanese Anime &amp; Manga\",\"question\":\"In &quot;Highschool DxD&quot;, Koneko Toujou is from what race?\",\"correct_answer\":\"Nekomata\",\"incorrect_answers\":[\"Kitsune\",\"Human\",\"Kappa\"]}]}");
// String sessionId = quizService.createSession(settings);
// int interval = 1000;
// int maxTime = 5000;
// long startTime = System.currentTimeMillis();
// Session session = null;
// while((System.currentTimeMillis() - maxTime) < startTime) {
// Optional<Session> retrieved = quizService.checkSession(sessionId);
// System.out.println(retrieved);
// if (retrieved.isPresent()) {
// System.out.print("Present!");
// session = retrieved.get();
// break;
// } else {
// try {
// Thread.sleep(interval);
// } catch (InterruptedException e) {
// Thread.currentThread().interrupt(); // Restore interrupted status
// fail("Thread was interrupted during sleep");
// }
// }
// }
// assertNotEquals(session, null);
// }
// public void testCalculateScore(){
// }
}