initial commit

This commit is contained in:
allard
2025-11-23 18:58:51 +01:00
commit 376a944abc
1553 changed files with 314731 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
<?xml version='1.0' encoding='utf-8'?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.ibm.codey.bank</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.ibm.codey.bank</groupId>
<artifactId>integration-tests</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.ibm.codey.bank</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Plugin to run functional tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,175 @@
package it.com.ibm.codey.loyalty;
import java.lang.reflect.Type;
import java.util.Map;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.Response;
import static org.junit.Assert.fail;
import com.ibm.codey.loyalty.accounts.json.UserRegistration;
import it.com.ibm.codey.loyalty.util.TestSecurityHelper;
public class EndpointTestBase {
protected static String USERS_BASEURL;
protected static String EVENTS_BASEURL;
protected static String TEST_USER_PREFIX;
protected static String TEST_USER;
protected static String TEST_PASSWORD;
protected static String userAccessToken;
protected static String TEST_ADMIN_USER;
protected static String TEST_ADMIN_PASSWORD;
protected static String adminAccessToken;
protected static final String USERS_ENDPOINT = "/loyalty/v1/users";
protected static final String USERS_SELF_ENDPOINT = "/loyalty/v1/users/self";
protected static final String USER_EVENTS_ENDPOINT = "/loyalty/v1/userEvents";
protected static final String USER_EVENTS_SELF_ENDPOINT = "/loyalty/v1/userEvents/self";
protected static final String USER_EVENTS_SELF_INFO_ENDPOINT = "/loyalty/v1/userEvents/self/info";
protected static final String EVENTS_ENDPOINT = "/loyalty/v1/events";
protected static boolean CONSENT_GIVEN = true;
protected static boolean CONSENT_NOT_GIVEN = false;
static {
USERS_BASEURL = System.getenv("USERS_BASEURL");
EVENTS_BASEURL = System.getenv("EVENTS_BASEURL");
TEST_USER_PREFIX = System.getenv("TEST_USER_PREFIX");
TEST_PASSWORD = System.getenv("TEST_PASSWORD");
TEST_ADMIN_USER = System.getenv("TEST_ADMIN_USER");
TEST_ADMIN_PASSWORD = System.getenv("TEST_ADMIN_PASSWORD");
}
private Client client;
protected void setup() {
client = ClientBuilder.newClient();
TEST_USER = TEST_USER_PREFIX + (int) ((Math.random() * 999999) + 1);
}
protected void teardown() {
client.close();
}
protected <T> T get(String baseUrl, String endpoint, Map<String, Object> queryParams, String accessToken, Response.Status expectedStatusCode, Type returnType) {
String url = baseUrl + endpoint;
WebTarget target = client.target(url);
if (queryParams != null) {
for (String key: queryParams.keySet()) {
target = target.queryParam(key, queryParams.get(key));
}
}
MultivaluedHashMap<String,Object> headers = new MultivaluedHashMap<String,Object>();
if (accessToken != null) {
String authHeader = "Bearer " + accessToken;
headers.putSingle(HttpHeaders.AUTHORIZATION, authHeader);
}
try (Response response = target.request().headers(headers).get()) {
checkStatusCode(url, response, expectedStatusCode);
if (returnType == Void.class) {
return null;
}
String jsonString = response.readEntity(String.class);
if (returnType.equals(String.class)) {
return (T)jsonString;
}
Jsonb jsonb = JsonbBuilder.create();
return jsonb.fromJson(jsonString, returnType);
}
}
protected <T> T put(String baseUrl, String endpoint, Object body, String accessToken, Response.Status expectedStatusCode, Class<T> returnType) {
String url = baseUrl + endpoint;
Jsonb jsonb = JsonbBuilder.create();
String jsonBody = jsonb.toJson(body);
MultivaluedHashMap<String,Object> headers = new MultivaluedHashMap<String,Object>();
if (accessToken != null) {
String authHeader = "Bearer " + accessToken;
headers.putSingle(HttpHeaders.AUTHORIZATION, authHeader);
}
try (Response response = client.target(url).request().headers(headers).buildPut(Entity.json(jsonBody)).invoke()) {
checkStatusCode(url, response, expectedStatusCode);
if (returnType == Void.class) {
return null;
}
String jsonString = response.readEntity(String.class);
if (returnType.equals(String.class)) {
return (T)jsonString;
}
return jsonb.fromJson(jsonString, returnType);
}
}
protected <T> T post(String baseUrl, String endpoint, Object body, String accessToken, Response.Status expectedStatusCode, Class<T> returnType) {
String url = baseUrl + endpoint;
Jsonb jsonb = JsonbBuilder.create();
String jsonBody = jsonb.toJson(body);
MultivaluedHashMap<String,Object> headers = new MultivaluedHashMap<String,Object>();
if (accessToken != null) {
String authHeader = "Bearer " + accessToken;
headers.putSingle(HttpHeaders.AUTHORIZATION, authHeader);
}
try (Response response = client.target(url).request().headers(headers).buildPost(Entity.json(jsonBody)).invoke()) {
checkStatusCode(url, response, expectedStatusCode);
if (returnType == Void.class) {
return null;
}
String jsonString = response.readEntity(String.class);
if (returnType.equals(String.class)) {
return (T)jsonString;
}
return jsonb.fromJson(jsonString, returnType);
}
}
protected void delete(String baseUrl, String endpoint, String accessToken, Response.Status expectedStatusCode) {
String url = baseUrl + endpoint;
MultivaluedHashMap<String,Object> headers = new MultivaluedHashMap<String,Object>();
if (accessToken != null) {
String authHeader = "Bearer " + accessToken;
headers.putSingle(HttpHeaders.AUTHORIZATION, authHeader);
}
try (Response response = client.target(url).request().headers(headers).buildDelete().invoke()) {
checkStatusCode(url, response, expectedStatusCode);
}
}
protected void setupUser() {
// Create a user in the user registry.
TestSecurityHelper.createUser(TEST_USER, TEST_PASSWORD);
// Log the user in and obtain an access token for invoking the API.
userAccessToken = TestSecurityHelper.signOn(TEST_USER, TEST_PASSWORD);
// Create user registration
UserRegistration userRegistration = new UserRegistration();
userRegistration.setConsentGiven(CONSENT_GIVEN);
post(USERS_BASEURL, USERS_ENDPOINT, userRegistration, userAccessToken, Response.Status.NO_CONTENT, Void.class);
}
protected void removeUser() {
// Use DELETE to remove user registration.
delete(USERS_BASEURL, USERS_SELF_ENDPOINT, userAccessToken, Response.Status.NO_CONTENT);
}
private void checkStatusCode(String url, Response response, Response.Status expectedStatusCode) {
if (expectedStatusCode.getStatusCode() != response.getStatus()) {
fail("Unexpected response code " + response.getStatus() +
" (expected " + expectedStatusCode.getStatusCode() +
") from " + url + " Response=" + response.readEntity(String.class));
}
}
}

View File

@@ -0,0 +1,66 @@
package it.com.ibm.codey.loyalty.accounts;
import javax.ws.rs.core.Response;
import static org.junit.Assert.assertEquals;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.ibm.codey.loyalty.accounts.json.UserRegistration;
import it.com.ibm.codey.loyalty.EndpointTestBase;
import it.com.ibm.codey.loyalty.util.TestSecurityHelper;
public class UserEndpointTest extends EndpointTestBase {
@Before
public void setup() {
super.setup();
}
@After
public void teardown() {
super.teardown();
}
@Test
public void testUserRegistrationAndDeletion() {
try {
setupUser();
// Use GET to get the user registration.
UserRegistration checkUserRegistration = get(USERS_BASEURL, USERS_SELF_ENDPOINT, null, userAccessToken, Response.Status.OK, UserRegistration.class);
assertEquals("Consent flag is incorrect", CONSENT_GIVEN, checkUserRegistration.isConsentGiven());
} finally {
removeUser();
}
}
@Test
public void testUserRegistrationModificationAndDeletion() {
try {
setupUser();
// Use PUT to change the user registration.
UserRegistration userRegistration = new UserRegistration();
userRegistration.setConsentGiven(CONSENT_NOT_GIVEN);
put(USERS_BASEURL, USERS_SELF_ENDPOINT, userRegistration, userAccessToken, Response.Status.NO_CONTENT, Void.class);
// Use GET to get the user registration.
UserRegistration checkUserRegistration = get(USERS_BASEURL, USERS_SELF_ENDPOINT, null, userAccessToken, Response.Status.OK, UserRegistration.class);
assertEquals("Consent flag is incorrect", CONSENT_NOT_GIVEN, checkUserRegistration.isConsentGiven());
} finally {
removeUser();
}
}
@Test
public void testAuthenticationFailure() {
// Make calls without an authentication header and verify they are rejected.
UserRegistration userRegistration = new UserRegistration();
userRegistration.setConsentGiven(CONSENT_GIVEN);
post(USERS_BASEURL, USERS_ENDPOINT, userRegistration, null, Response.Status.UNAUTHORIZED, Void.class);
get(USERS_BASEURL, USERS_SELF_ENDPOINT, null, null, Response.Status.UNAUTHORIZED, Void.class);
put(USERS_BASEURL, USERS_SELF_ENDPOINT, userRegistration, null, Response.Status.UNAUTHORIZED, Void.class);
delete(USERS_BASEURL, USERS_SELF_ENDPOINT, null, Response.Status.UNAUTHORIZED);
}
}

View File

@@ -0,0 +1,177 @@
package it.com.ibm.codey.loyalty.accounts;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.ws.rs.core.Response;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.ibm.codey.loyalty.accounts.json.UserEventCheckIn;
import com.ibm.codey.loyalty.accounts.json.UserEventInfo;
import com.ibm.codey.loyalty.accounts.json.UserRegistration;
import com.ibm.codey.loyalty.catalog.json.EventDefinition;
import it.com.ibm.codey.loyalty.EndpointTestBase;
import it.com.ibm.codey.loyalty.util.TestSecurityHelper;
public class UserEventsEndpointTest extends EndpointTestBase {
private static String normalPointsEventId, doublePointsEventId;
private static final int NORMAL_POINTS = 10;
private static final int DOUBLE_POINTS = NORMAL_POINTS*2;
private static final String NORMAL_POINTS_EVENT_NAME = "test event normal points";
private static final String DOUBLE_POINTS_EVENT_NAME = "test event double points";
private static boolean eventsCreated = false;
@Before
public void setup() {
super.setup();
// Create events. These are reused for all tests.
// This isn't done in a BeforeClass method because it depends on the non-static post() method in the superclass.
if (!eventsCreated) {
adminAccessToken = TestSecurityHelper.signOn(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD);
normalPointsEventId = createEvent(NORMAL_POINTS_EVENT_NAME, NORMAL_POINTS);
doublePointsEventId = createEvent(DOUBLE_POINTS_EVENT_NAME, DOUBLE_POINTS);
eventsCreated = true;
}
}
@After
public void teardown() {
super.teardown();
}
@Test
public void testEventCheckin() {
try {
setupUser();
// Verify no events attended or points earned yet
UserEventInfo userEventInfo = get(USERS_BASEURL, USER_EVENTS_SELF_INFO_ENDPOINT, null, userAccessToken, Response.Status.OK, UserEventInfo.class);
assertEquals("initial event count is incorrect", 0, userEventInfo.getEventCount());
assertEquals("initial points earned is incorrect", 0, userEventInfo.getPointsEarned());
// Check in to first event
UserEventCheckIn checkIn1 = new UserEventCheckIn();
checkIn1.setEventId(normalPointsEventId);
post(USERS_BASEURL, USER_EVENTS_ENDPOINT, checkIn1, userAccessToken, Response.Status.NO_CONTENT, Void.class);
// Verify check in to first event
String[] eventIds = get(USERS_BASEURL, USER_EVENTS_SELF_ENDPOINT, null, userAccessToken, Response.Status.OK, String[].class);
assertEquals("GET returned incorrect number of events checked in", 1, eventIds.length);
assertEquals("Event id is incorrect", normalPointsEventId, eventIds[0]);
// Verify points earned
UserEventInfo userEventInfo2 = get(USERS_BASEURL, USER_EVENTS_SELF_INFO_ENDPOINT, null, userAccessToken, Response.Status.OK, UserEventInfo.class);
assertEquals("event count is incorrect", 1, userEventInfo2.getEventCount());
assertEquals("points earned is incorrect", NORMAL_POINTS, userEventInfo2.getPointsEarned());
// Check in to second event
UserEventCheckIn checkIn2 = new UserEventCheckIn();
checkIn2.setEventId(doublePointsEventId);
post(USERS_BASEURL, USER_EVENTS_ENDPOINT, checkIn2, userAccessToken, Response.Status.NO_CONTENT, Void.class);
// Verify check in to both events
String[] eventIds2 = get(USERS_BASEURL, USER_EVENTS_SELF_ENDPOINT, null, userAccessToken, Response.Status.OK, String[].class);
assertEquals("GET returned incorrect number of events checked in", 2, eventIds2.length);
if (eventIds2[0].equals(normalPointsEventId)) {
assertEquals("Event id [1] is incorrect", doublePointsEventId, eventIds2[1]);
} else {
assertEquals("Event id [0] is incorrect", doublePointsEventId, eventIds2[0]);
assertEquals("Event id [1] is incorrect", normalPointsEventId, eventIds2[1]);
}
// Verify points earned
UserEventInfo userEventInfo3 = get(USERS_BASEURL, USER_EVENTS_SELF_INFO_ENDPOINT, null, userAccessToken, Response.Status.OK, UserEventInfo.class);
assertEquals("event count is incorrect", 2, userEventInfo3.getEventCount());
assertEquals("points earned is incorrect", NORMAL_POINTS+DOUBLE_POINTS, userEventInfo3.getPointsEarned());
} finally {
removeUser();
}
}
@Test
public void testDuplicateEventCheckin() {
try {
setupUser();
// Check in to first event
UserEventCheckIn checkIn1 = new UserEventCheckIn();
checkIn1.setEventId(normalPointsEventId);
post(USERS_BASEURL, USER_EVENTS_ENDPOINT, checkIn1, userAccessToken, Response.Status.NO_CONTENT, Void.class);
// Check in to first event again
post(USERS_BASEURL, USER_EVENTS_ENDPOINT, checkIn1, userAccessToken, Response.Status.BAD_REQUEST, Void.class);
} finally {
removeUser();
}
}
@Test
public void testWithNonConsentedUser() {
try {
setupUser();
// Use PUT to change user registration to withdraw consent
UserRegistration userRegistration = new UserRegistration();
userRegistration.setConsentGiven(CONSENT_NOT_GIVEN);
put(USERS_BASEURL, USERS_SELF_ENDPOINT, userRegistration, userAccessToken, Response.Status.NO_CONTENT, Void.class);
// Try to check into an event or get information
UserEventCheckIn checkIn1 = new UserEventCheckIn();
checkIn1.setEventId(normalPointsEventId);
post(USERS_BASEURL, USER_EVENTS_ENDPOINT, checkIn1, userAccessToken, Response.Status.CONFLICT, Void.class);
get(USERS_BASEURL, USER_EVENTS_SELF_ENDPOINT, null, userAccessToken, Response.Status.CONFLICT, Void.class);
get(USERS_BASEURL, USER_EVENTS_SELF_INFO_ENDPOINT, null, userAccessToken, Response.Status.CONFLICT, Void.class);
} finally {
removeUser();
}
}
@Test
public void testWithUnregisteredUser() {
setupUser();
removeUser();
// Try to check into an event or get information
UserEventCheckIn checkIn1 = new UserEventCheckIn();
checkIn1.setEventId(normalPointsEventId);
post(USERS_BASEURL, USER_EVENTS_ENDPOINT, checkIn1, userAccessToken, Response.Status.BAD_REQUEST, Void.class);
get(USERS_BASEURL, USER_EVENTS_SELF_ENDPOINT, null, userAccessToken, Response.Status.BAD_REQUEST, Void.class);
get(USERS_BASEURL, USER_EVENTS_SELF_INFO_ENDPOINT, null, userAccessToken, Response.Status.BAD_REQUEST, Void.class);
}
@Test
public void testAuthenticationFailure() {
// Make calls without an authentication header
UserEventCheckIn checkIn1 = new UserEventCheckIn();
checkIn1.setEventId(normalPointsEventId);
post(USERS_BASEURL, USER_EVENTS_ENDPOINT, checkIn1, null, Response.Status.UNAUTHORIZED, Void.class);
get(USERS_BASEURL, USER_EVENTS_SELF_ENDPOINT, null, null, Response.Status.UNAUTHORIZED, Void.class);
get(USERS_BASEURL, USER_EVENTS_SELF_INFO_ENDPOINT, null, null, Response.Status.UNAUTHORIZED, Void.class);
}
@Test
public void testBadEventId() {
String badEventId1 = "1";
String badEventId2 = "/deadbeef-0000-0000-0000-badbadbadbad";
UserEventCheckIn checkIn1 = new UserEventCheckIn();
checkIn1.setEventId(badEventId1);
post(USERS_BASEURL, USER_EVENTS_ENDPOINT, checkIn1, userAccessToken, Response.Status.BAD_REQUEST, Void.class);
UserEventCheckIn checkIn2 = new UserEventCheckIn();
checkIn2.setEventId(badEventId2);
post(USERS_BASEURL, USER_EVENTS_ENDPOINT, checkIn2, userAccessToken, Response.Status.BAD_REQUEST, Void.class);
}
private String createEvent(String eventName, int pointValue) {
EventDefinition eventDefinition = new EventDefinition();
eventDefinition.setEventName(eventName);
eventDefinition.setPointValue(pointValue);
String eventId = post(EVENTS_BASEURL, EVENTS_ENDPOINT, eventDefinition, adminAccessToken, Response.Status.CREATED, String.class);
return eventId;
}
}

View File

@@ -0,0 +1,175 @@
package it.com.ibm.codey.loyalty.catalog;
import java.time.OffsetDateTime;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
import org.apache.commons.lang3.RandomStringUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.ibm.codey.loyalty.catalog.json.EventDefinition;
import it.com.ibm.codey.loyalty.EndpointTestBase;
import it.com.ibm.codey.loyalty.util.TestSecurityHelper;
public class EventsEndpointTest extends EndpointTestBase {
private String eventName;
private int pointValue;
private String eventDescription;
private String eventLocation;
private OffsetDateTime startTime;
private OffsetDateTime endTime;
@Before
public void setup() {
super.setup();
// Set up a normal user to test methods which don't require admin.
setupUser();
// Set up an admin user.
adminAccessToken = TestSecurityHelper.signOn(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD);
// Set up event attributes.
String suffix = RandomStringUtils.randomAlphabetic(8);
eventName = "test event " + suffix;
eventDescription = "all about " + suffix;
eventLocation = "at " + suffix;
startTime = OffsetDateTime.now();
endTime = OffsetDateTime.now().plusHours(1);
pointValue = (int) ((Math.random() * 99) + 1);
}
@After
public void teardown() {
removeUser();
super.teardown();
}
@Test
public void testCreateEvent() {
// Use POST to create an event.
EventDefinition eventDefinition = new EventDefinition();
eventDefinition.setEventName(eventName);
eventDefinition.setPointValue(pointValue);
eventDefinition.setEventDescription(eventDescription);
eventDefinition.setEventLocation(eventLocation);
eventDefinition.setStartTime(startTime);
eventDefinition.setEndTime(endTime);
String eventId = post(EVENTS_BASEURL, EVENTS_ENDPOINT, eventDefinition, adminAccessToken, Response.Status.CREATED, String.class);
// Use GET to get the event. This method does not require admin.
EventDefinition checkEventDefinition = get(EVENTS_BASEURL, EVENTS_ENDPOINT + '/' + eventId, null, userAccessToken, Response.Status.OK, EventDefinition.class);
assertEquals("Event name is incorrect", eventName, checkEventDefinition.getEventName());
assertEquals("Point value is incorrect", pointValue, checkEventDefinition.getPointValue());
assertEquals("Event description is incorrect", eventDescription, checkEventDefinition.getEventDescription());
assertEquals("Event location is incorrect", eventLocation, checkEventDefinition.getEventLocation());
assertEquals("Event start time is incorrect", startTime.toInstant(), checkEventDefinition.getStartTime().toInstant()); // Use toInstant to normalize timezones
assertEquals("Event end time is incorrect", endTime.toInstant(), checkEventDefinition.getEndTime().toInstant());
}
@Test
public void testGetAllEvents() {
// Use POST to create an event. An admin user must do this.
EventDefinition eventDefinition = new EventDefinition();
eventDefinition.setEventName(eventName);
eventDefinition.setPointValue(pointValue);
eventDefinition.setEventDescription(eventDescription);
eventDefinition.setEventLocation(eventLocation);
eventDefinition.setStartTime(startTime);
eventDefinition.setEndTime(endTime);
String eventId = post(EVENTS_BASEURL, EVENTS_ENDPOINT, eventDefinition, adminAccessToken, Response.Status.CREATED, String.class);
// Use GET to get all events. This method does not require admin.
GenericType<Map<String, EventDefinition>> eventDefinitionMapType = new GenericType<Map<String, EventDefinition>>() {};
Map<String, EventDefinition> eventDefinitionsMap = get(EVENTS_BASEURL, EVENTS_ENDPOINT, null, userAccessToken, Response.Status.OK, eventDefinitionMapType.getType());
assertNotNull("GET did not return any events", eventDefinitionsMap);
EventDefinition checkEventDefinition = eventDefinitionsMap.get(eventId);
assertNotNull("GET did not return the event that was just created", checkEventDefinition);
assertEquals("Event name is incorrect", eventName, checkEventDefinition.getEventName());
assertEquals("Point value is incorrect", pointValue, checkEventDefinition.getPointValue());
assertEquals("Event description is incorrect", eventDescription, checkEventDefinition.getEventDescription());
assertEquals("Event location is incorrect", eventLocation, checkEventDefinition.getEventLocation());
assertEquals("Event start time is incorrect", startTime.toInstant(), checkEventDefinition.getStartTime().toInstant()); // Use toInstant to normalize timezones
assertEquals("Event end time is incorrect", endTime.toInstant(), checkEventDefinition.getEndTime().toInstant());
}
@Test
public void testSearchEvent() {
// Use POST to create an event. An admin user must do this.
EventDefinition eventDefinition = new EventDefinition();
eventDefinition.setEventName(eventName);
eventDefinition.setPointValue(pointValue);
eventDefinition.setEventDescription(eventDescription);
eventDefinition.setEventLocation(eventLocation);
eventDefinition.setStartTime(startTime);
eventDefinition.setEndTime(endTime);
String eventId = post(EVENTS_BASEURL, EVENTS_ENDPOINT, eventDefinition, adminAccessToken, Response.Status.CREATED, String.class);
// Use GET to search for this event. This method does not require admin.
Map<String,Object> queryParams = Collections.singletonMap("id", eventId);
GenericType<Map<String, EventDefinition>> eventDefinitionMapType = new GenericType<Map<String, EventDefinition>>() {};
Map<String, EventDefinition> eventDefinitionsMap = get(EVENTS_BASEURL, EVENTS_ENDPOINT, queryParams, userAccessToken, Response.Status.OK, eventDefinitionMapType.getType());
assertNotNull("GET did not return any events", eventDefinitionsMap);
EventDefinition checkEventDefinition = eventDefinitionsMap.get(eventId);
assertNotNull("GET did not return the event that was just created", checkEventDefinition);
assertEquals("Event name is incorrect", eventName, checkEventDefinition.getEventName());
assertEquals("Point value is incorrect", pointValue, checkEventDefinition.getPointValue());
assertEquals("Event description is incorrect", eventDescription, checkEventDefinition.getEventDescription());
assertEquals("Event location is incorrect", eventLocation, checkEventDefinition.getEventLocation());
assertEquals("Event start time is incorrect", startTime.toInstant(), checkEventDefinition.getStartTime().toInstant()); // Use toInstant to normalize timezones
assertEquals("Event end time is incorrect", endTime.toInstant(), checkEventDefinition.getEndTime().toInstant());
}
@Test
public void testCreateAndUpdateEvent() {
// Use POST to create an event. An admin user must do this.
EventDefinition eventDefinition = new EventDefinition();
eventDefinition.setEventName(eventName);
eventDefinition.setPointValue(pointValue);
eventDefinition.setEventDescription(eventDescription);
eventDefinition.setEventLocation(eventLocation);
eventDefinition.setStartTime(startTime);
eventDefinition.setEndTime(endTime);
String eventId = post(EVENTS_BASEURL, EVENTS_ENDPOINT, eventDefinition, adminAccessToken, Response.Status.CREATED, String.class);
// Use PUT to modify the event. An admin user must do this.
eventDefinition.setEventName(eventName + eventName);
eventDefinition.setPointValue(pointValue*2);
put(EVENTS_BASEURL, EVENTS_ENDPOINT + '/' + eventId, eventDefinition, adminAccessToken, Response.Status.NO_CONTENT, Void.class);
// Use GET to get the event. This method does not require admin.
EventDefinition checkEventDefinition = get(EVENTS_BASEURL, EVENTS_ENDPOINT + '/' + eventId, null, userAccessToken, Response.Status.OK, EventDefinition.class);
assertEquals("Event name is incorrect", eventDefinition.getEventName(), checkEventDefinition.getEventName());
assertEquals("Point value is incorrect", eventDefinition.getPointValue(), checkEventDefinition.getPointValue());
assertEquals("Event description is incorrect", eventDescription, checkEventDefinition.getEventDescription());
assertEquals("Event location is incorrect", eventLocation, checkEventDefinition.getEventLocation());
assertEquals("Event start time is incorrect", startTime.toInstant(), checkEventDefinition.getStartTime().toInstant()); // Use toInstant to normalize timezones
assertEquals("Event end time is incorrect", endTime.toInstant(), checkEventDefinition.getEndTime().toInstant());
}
@Test
public void testAuthenticationFailure() {
// Make calls without an authentication header.
EventDefinition eventDefinition = new EventDefinition();
eventDefinition.setEventName(eventName);
eventDefinition.setPointValue(pointValue);
post(EVENTS_BASEURL, EVENTS_ENDPOINT, eventDefinition, null, Response.Status.UNAUTHORIZED, Void.class);
put(EVENTS_BASEURL, EVENTS_ENDPOINT + "/deadbeef-0000-0000-0000-badbadbadbad", eventDefinition, null, Response.Status.UNAUTHORIZED, Void.class);
get(EVENTS_BASEURL, EVENTS_ENDPOINT, null, null, Response.Status.UNAUTHORIZED, Void.class);
get(EVENTS_BASEURL, EVENTS_ENDPOINT + "/deadbeef-0000-0000-0000-badbadbadbad", null, null, Response.Status.UNAUTHORIZED, Void.class);
}
@Test
public void testAuthorizationFailure() {
// Normal users do not have access to POST or PUT.
EventDefinition eventDefinition = new EventDefinition();
eventDefinition.setEventName(eventName);
eventDefinition.setPointValue(pointValue);
post(EVENTS_BASEURL, EVENTS_ENDPOINT, eventDefinition, userAccessToken, Response.Status.FORBIDDEN, Void.class);
put(EVENTS_BASEURL, EVENTS_ENDPOINT + "/deadbeef-0000-0000-0000-badbadbadbad", eventDefinition, userAccessToken, Response.Status.FORBIDDEN, Void.class);
}
}

View File

@@ -0,0 +1,104 @@
package it.com.ibm.codey.loyalty.util;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import javax.json.Json;
import javax.json.JsonObject;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.cxf.jaxrs.provider.jsrjsonp.JsrJsonpProvider;
public class TestSecurityHelper {
private static String APPID_SERVICE_URL;
private static String APPID_TENANTID;
private static String IAM_APIKEY;
private static String IAM_SERVICE_URL;
private static String OIDC_ISSUERIDENTIFIER;
private static String OIDC_CLIENTID;
private static String OIDC_CLIENTPASSWORD;
private static String iamAuthHeader;
private static String oidcAuthHeader;
static {
APPID_SERVICE_URL = System.getenv("APPID_SERVICE_URL");
APPID_TENANTID = System.getenv("APPID_TENANTID");
IAM_APIKEY = System.getenv("IAM_APIKEY");
IAM_SERVICE_URL = System.getenv("IAM_SERVICE_URL");
OIDC_ISSUERIDENTIFIER = System.getenv("OIDC_ISSUERIDENTIFIER");
OIDC_CLIENTID = System.getenv("OIDC_CLIENTID");
OIDC_CLIENTPASSWORD = System.getenv("OIDC_CLIENTPASSWORD");
String oidcClientCredentials = OIDC_CLIENTID + ":" + OIDC_CLIENTPASSWORD;
oidcAuthHeader = "Basic " + Base64.getEncoder().encodeToString(oidcClientCredentials.getBytes(StandardCharsets.UTF_8));
}
public static void createUser(String user, String password) {
Client client = ClientBuilder.newClient();
client.register(JsrJsonpProvider.class);
// Get IAM bearer token when creating the first user. The token can be reused after that.
if (iamAuthHeader == null) {
Form form = new Form();
form.param("grant_type", "urn:ibm:params:oauth:grant-type:apikey");
form.param("apikey", IAM_APIKEY);
String iamToken;
try (Response response = client.target(IAM_SERVICE_URL).request(MediaType.APPLICATION_JSON).buildPost(Entity.form(form)).invoke()) {
if (response.getStatus() != Response.Status.OK.getStatusCode()) {
throw new RuntimeException("TEST CASE FAILURE. Cannot obtain IAM access token. Status code " + response.getStatus() + " Response =" + response.readEntity(JsonObject.class));
}
JsonObject obj = response.readEntity(JsonObject.class);
iamToken = obj.getString("access_token");
}
iamAuthHeader = "Bearer " + iamToken;
}
// Create the user
JsonObject request = Json.createObjectBuilder()
.add("userName", user)
.add("password", password)
.add("active", true)
.add("emails", Json.createArrayBuilder()
.add(Json.createObjectBuilder()
.add("value", "ibmtestloyalty@yopmail.com")
.add("primary", true))
).build();
String createUserURL = APPID_SERVICE_URL + "/management/v4/" + APPID_TENANTID + "/cloud_directory/Users";
try (Response response = client.target(createUserURL).request(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, iamAuthHeader).buildPost(Entity.json(request)).invoke()) {
if (response.getStatus() != Response.Status.CREATED.getStatusCode()) {
throw new RuntimeException("TEST CASE FAILURE. Cannot create user. Status code " + response.getStatus() + " Response =" + response.readEntity(JsonObject.class));
}
}
}
public static String signOn(String user, String password) {
String url = OIDC_ISSUERIDENTIFIER + "/token";
Form form = new Form();
form.param("grant_type", "password");
form.param("username", user);
form.param("password", password);
Client client = ClientBuilder.newClient();
client.register(JsrJsonpProvider.class);
try (Response response = client.target(url).request(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, oidcAuthHeader).buildPost(Entity.form(form)).invoke()) {
if (response.getStatus() != Response.Status.OK.getStatusCode()) {
throw new RuntimeException("TEST CASE FAILURE. Cannot obtain access token. Status code " + response.getStatus() + " Response =" + response.readEntity(JsonObject.class));
}
JsonObject obj = response.readEntity(JsonObject.class);
return obj.getString("access_token");
}
}
}