diff --git a/samples/get-about/pom.xml b/samples/get-about/pom.xml
new file mode 100644
index 00000000..9d7f21f2
--- /dev/null
+++ b/samples/get-about/pom.xml
@@ -0,0 +1,22 @@
+
+
+ 4.0.0
+
+ dev.learning.xapi.samples
+ xapi-samples-build
+ 1.0.6-SNAPSHOT
+
+ get-about
+ Get xAPI About Sample
+ Get xAPI About
+
+
+ dev.learning.xapi
+ xapi-client
+
+
+ dev.learning.xapi.samples
+ core
+
+
+
diff --git a/samples/get-about/src/main/java/dev/learning/xapi/samples/getabout/GetAboutApplication.java b/samples/get-about/src/main/java/dev/learning/xapi/samples/getabout/GetAboutApplication.java
new file mode 100644
index 00000000..e0141a29
--- /dev/null
+++ b/samples/get-about/src/main/java/dev/learning/xapi/samples/getabout/GetAboutApplication.java
@@ -0,0 +1,52 @@
+package dev.learning.xapi.samples.getabout;
+
+import dev.learning.xapi.client.XapiClient;
+import dev.learning.xapi.model.About;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.reactive.function.client.WebClient;
+
+/**
+ * Sample using xAPI client to get about.
+ *
+ * @author Thomas Turrell-Croft
+ */
+@SpringBootApplication
+public class GetAboutApplication implements CommandLineRunner {
+
+ private final XapiClient client;
+
+ /**
+ * Constructor for application. In this sample the WebClient.Builder instance is injected by the
+ * Spring Framework.
+ */
+ public GetAboutApplication(WebClient.Builder webClientBuilder) {
+
+ webClientBuilder
+ // Change for the URL of your LRS
+ .baseUrl("https://example.com/xapi/")
+ // Set the Authorization value
+ .defaultHeader("Authorization", "")
+
+ .build();
+
+ client = new XapiClient(webClientBuilder);
+ }
+
+ public static void main(String[] args) {
+ SpringApplication.run(GetAboutApplication.class, args).close();
+ }
+
+ @Override
+ public void run(String... args) throws Exception {
+
+ // Get About
+ ResponseEntity response = client.getAbout().block();
+
+ // Print the returned activity to the console
+ System.out.println(response.getBody());
+ }
+
+}
diff --git a/samples/pom.xml b/samples/pom.xml
index 14b349a4..f674817f 100644
--- a/samples/pom.xml
+++ b/samples/pom.xml
@@ -35,6 +35,7 @@
core
delete-agent-profile
delete-state
+ get-about
get-activity
get-agent-profile
get-agent-profiles
diff --git a/xapi-client/src/main/java/dev/learning/xapi/client/GetStatementsRequest.java b/xapi-client/src/main/java/dev/learning/xapi/client/GetStatementsRequest.java
index cf6005f4..27414d5c 100644
--- a/xapi-client/src/main/java/dev/learning/xapi/client/GetStatementsRequest.java
+++ b/xapi-client/src/main/java/dev/learning/xapi/client/GetStatementsRequest.java
@@ -207,8 +207,6 @@ public Builder activity(String activity) {
return this;
}
-
-
/**
* Sets the registration.
*
diff --git a/xapi-client/src/main/java/dev/learning/xapi/client/XapiClient.java b/xapi-client/src/main/java/dev/learning/xapi/client/XapiClient.java
index 26d5102f..2eeff738 100644
--- a/xapi-client/src/main/java/dev/learning/xapi/client/XapiClient.java
+++ b/xapi-client/src/main/java/dev/learning/xapi/client/XapiClient.java
@@ -4,6 +4,7 @@
package dev.learning.xapi.client;
+import dev.learning.xapi.model.About;
import dev.learning.xapi.model.Activity;
import dev.learning.xapi.model.Person;
import dev.learning.xapi.model.Statement;
@@ -45,6 +46,8 @@ public XapiClient(WebClient.Builder builder) {
.build();
}
+ // Statement Resource
+
/**
* Gets a Statement.
*
@@ -349,6 +352,8 @@ public Mono> getMoreStatements(
}
+ // State Resource
+
/**
* Gets a single document specified by the given stateId activity, agent, and optional
* registration.
@@ -655,6 +660,96 @@ public Mono> deleteStates(
}
+ // Agents Resource
+
+ /**
+ * Return a special, Person Object for a specified Agent. The Person Object is very similar to an
+ * Agent Object, but instead of each attribute having a single value, each attribute has an array
+ * value, and it is legal to include multiple identifying properties.
+ *
+ * @param request The parameters of the get agents request
+ *
+ * @return the ResponseEntity
+ */
+ public Mono> getAgents(GetAgentsRequest request) {
+
+ Map queryParams = new HashMap<>();
+
+ return this.webClient
+
+ .method(request.getMethod())
+
+ .uri(u -> request.url(u, queryParams).build(queryParams))
+
+ .retrieve()
+
+ .toEntity(Person.class);
+
+ }
+
+ /**
+ * Return a special, Person Object for a specified Agent. The Person Object is very similar to an
+ * Agent Object, but instead of each attribute having a single value, each attribute has an array
+ * value, and it is legal to include multiple identifying properties.
+ *
+ * @param request The Consumer Builder for the get agents request
+ *
+ * @return the ResponseEntity
+ */
+ public Mono> getAgents(Consumer request) {
+
+ final GetAgentsRequest.Builder builder = GetAgentsRequest.builder();
+
+ request.accept(builder);
+
+ return getAgents(builder.build());
+
+ }
+
+ // Activities Resource
+
+ /**
+ * Loads the complete Activity Object specified.
+ *
+ * @param request The parameters of the get activity request
+ *
+ * @return the ResponseEntity
+ */
+ public Mono> getActivity(GetActivityRequest request) {
+
+ Map queryParams = new HashMap<>();
+
+ return this.webClient
+
+ .method(request.getMethod())
+
+ .uri(u -> request.url(u, queryParams).build(queryParams))
+
+ .retrieve()
+
+ .toEntity(Activity.class);
+
+ }
+
+ /**
+ * Loads the complete Activity Object specified.
+ *
+ * @param request The Consumer Builder for the get activity request
+ *
+ * @return the ResponseEntity
+ */
+ public Mono> getActivity(Consumer request) {
+
+ final GetActivityRequest.Builder builder = GetActivityRequest.builder();
+
+ request.accept(builder);
+
+ return getActivity(builder.build());
+
+ }
+
+ // Agent Profile Resource
+
/**
* Gets a single agent profile by the given agent and profileId.
*
@@ -905,87 +1000,25 @@ public Mono> getAgentProfiles(
}
- /**
- * Loads the complete Activity Object specified.
- *
- * @param request The parameters of the get activity request
- *
- * @return the ResponseEntity
- */
- public Mono> getActivity(GetActivityRequest request) {
-
- Map queryParams = new HashMap<>();
-
- return this.webClient
-
- .method(request.getMethod())
-
- .uri(u -> request.url(u, queryParams).build(queryParams))
-
- .retrieve()
-
- .toEntity(Activity.class);
-
- }
+ // About Resource
/**
- * Loads the complete Activity Object specified.
- *
- * @param request The Consumer Builder for the get activity request
+ * Returns JSON Object containing information about this LRS, including the xAPI version
+ * supported.
*
* @return the ResponseEntity
*/
- public Mono> getActivity(Consumer request) {
-
- final GetActivityRequest.Builder builder = GetActivityRequest.builder();
-
- request.accept(builder);
-
- return getActivity(builder.build());
-
- }
-
- /**
- * Return a special, Person Object for a specified Agent. The Person Object is very similar to an
- * Agent Object, but instead of each attribute having a single value, each attribute has an array
- * value, and it is legal to include multiple identifying properties.
- *
- * @param request The parameters of the get agents request
- *
- * @return the ResponseEntity
- */
- public Mono> getAgents(GetAgentsRequest request) {
-
- Map queryParams = new HashMap<>();
+ public Mono> getAbout() {
return this.webClient
- .method(request.getMethod())
+ .get()
- .uri(u -> request.url(u, queryParams).build(queryParams))
+ .uri(u -> u.path("/about").build())
.retrieve()
- .toEntity(Person.class);
-
- }
-
- /**
- * Return a special, Person Object for a specified Agent. The Person Object is very similar to an
- * Agent Object, but instead of each attribute having a single value, each attribute has an array
- * value, and it is legal to include multiple identifying properties.
- *
- * @param request The Consumer Builder for the get agents request
- *
- * @return the ResponseEntity
- */
- public Mono> getAgents(Consumer request) {
-
- final GetAgentsRequest.Builder builder = GetAgentsRequest.builder();
-
- request.accept(builder);
-
- return getAgents(builder.build());
+ .toEntity(About.class);
}
diff --git a/xapi-client/src/test/java/dev/learning/xapi/client/XapiClientTests.java b/xapi-client/src/test/java/dev/learning/xapi/client/XapiClientTests.java
index 25c4e965..6391c0cd 100644
--- a/xapi-client/src/test/java/dev/learning/xapi/client/XapiClientTests.java
+++ b/xapi-client/src/test/java/dev/learning/xapi/client/XapiClientTests.java
@@ -6,6 +6,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import dev.learning.xapi.model.About;
import dev.learning.xapi.model.Activity;
import dev.learning.xapi.model.Person;
import dev.learning.xapi.model.Statement;
@@ -416,7 +417,6 @@ void whenGettingStatementsThenMethodIsGet() throws InterruptedException {
assertThat(recordedRequest.getMethod(), is("GET"));
}
-
@Test
void whenGettingStatementsThenPathIsExpected() throws InterruptedException {
@@ -529,8 +529,6 @@ void whenGettingStatementsWithActivityParameterThenPathIsExpected() throws Inter
is("/statements?activity=https%3A%2F%2Fexample.com%2Factivity%2F1"));
}
-
-
@Test
void whenGettingMoreStatementsThenRequestMethodIsGet() throws InterruptedException {
@@ -1313,7 +1311,6 @@ void whenGettingASingleAgentProfileThenMethodIsGet() throws InterruptedException
assertThat(recordedRequest.getMethod(), is("GET"));
}
-
@Test
void whenGettingASingleAgentProfileThenPathIsExpected() throws InterruptedException {
@@ -1487,8 +1484,6 @@ void whenPuttingASingleAgentProfileWithoutContentTypeThenBodyIsExpected()
is("{\"firstName\":\"A N\",\"lastName\":\"Other\"}"));
}
-
-
// Post Single Agent Profile
@Test
@@ -1605,8 +1600,6 @@ void whenPostingASingleAgentProfileWithoutContentTypeThenBodyIsExpected()
is("{\"firstName\":\"A N\",\"lastName\":\"Other\"}"));
}
-
-
@Test
void whenGettingProfilesThenMethodIsGet() throws InterruptedException {
@@ -1646,7 +1639,6 @@ void whenGettingProfilesThenPathIsExpected() throws InterruptedException {
"/agents/profile?agent=%7B%22name%22%3A%22A%20N%20Other%22%2C%22mbox%22%3A%22mailto%3Aanother%40example.com%22%7D"));
}
-
@Test
void whenGettingProfilesWithSinceParameterThenPathIsExpected() throws InterruptedException {
@@ -1722,8 +1714,6 @@ void whenGettingActivityThenBodyIsInstanceOfActivity() throws InterruptedExcepti
assertThat(response.getBody(), instanceOf(Activity.class));
}
-
-
// Get Agents
@Test
@@ -1772,7 +1762,59 @@ void whenGettingAgentsThenBodyIsInstanceOfPerson() throws InterruptedException {
assertThat(response.getBody(), instanceOf(Person.class));
}
+ // Get About
+
+ @Test
+ void whenGettingAboutThenMethodIsGet() throws InterruptedException {
+
+ mockWebServer.enqueue(new MockResponse().setStatus("HTTP/1.1 200 OK")
+
+ .setBody(
+ "{\"extensions\":{\"https://example.com/extensions/test\":{\"name\":\"Example extension\"}},\"version\":[\"0.9\",\"0.95\",\"1.0.3\"]}")
+ .addHeader("Content-Type", "application/json; charset=utf-8"));
+ // When Getting About
+ client.getAbout().block();
+
+ RecordedRequest recordedRequest = mockWebServer.takeRequest();
+
+ // Then Method Is Get
+ assertThat(recordedRequest.getMethod(), is("GET"));
+ }
+
+ @Test
+ void whenGettingAboutThenPathIsExpected() throws InterruptedException {
+
+ mockWebServer.enqueue(new MockResponse().setStatus("HTTP/1.1 200 OK")
+
+ .setBody(
+ "{\"extensions\":{\"https://example.com/extensions/test\":{\"name\":\"Example extension\"}},\"version\":[\"0.9\",\"0.95\",\"1.0.3\"]}")
+ .addHeader("Content-Type", "application/json; charset=utf-8"));
+
+ // When Getting About
+ client.getAbout().block();
+
+ RecordedRequest recordedRequest = mockWebServer.takeRequest();
+
+ // Then Path Is Expected
+ assertThat(recordedRequest.getPath(), is("/about"));
+ }
+
+ @Test
+ void whenGettingAboutThenBodyIsInstanceOfAbout() throws InterruptedException {
+
+ mockWebServer.enqueue(new MockResponse().setStatus("HTTP/1.1 200 OK")
+
+ .setBody(
+ "{\"extensions\":{\"https://example.com/extensions/test\":{\"name\":\"Example extension\"}},\"version\":[\"0.9\",\"0.95\",\"1.0.3\"]}")
+ .addHeader("Content-Type", "application/json; charset=utf-8"));
+
+ // When Getting About
+ var response = client.getAbout().block();
+
+ // Then Body Is Instance Of About
+ assertThat(response.getBody(), instanceOf(About.class));
+ }
@Getter
private static class SamplePerson {