Skip to content

Commit 35f8c49

Browse files
committed
AJ-1234: Add WsmPactTest
1 parent 7a031e7 commit 35f8c49

File tree

1 file changed

+176
-0
lines changed
  • service/src/test/java/org/databiosphere/workspacedataservice/pact

1 file changed

+176
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
package org.databiosphere.workspacedataservice.pact;
2+
3+
import static au.com.dius.pact.consumer.dsl.LambdaDsl.newJsonBody;
4+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
5+
import static org.junit.jupiter.api.Assertions.assertThrows;
6+
7+
import au.com.dius.pact.consumer.MockServer;
8+
import au.com.dius.pact.consumer.dsl.DslPart;
9+
import au.com.dius.pact.consumer.dsl.PactDslWithProvider;
10+
import au.com.dius.pact.consumer.junit5.PactConsumerTestExt;
11+
import au.com.dius.pact.consumer.junit5.PactTestFor;
12+
import au.com.dius.pact.core.model.PactSpecVersion;
13+
import au.com.dius.pact.core.model.RequestResponsePact;
14+
import au.com.dius.pact.core.model.annotations.Pact;
15+
import bio.terra.datarepo.model.SnapshotModel;
16+
import bio.terra.workspace.model.CloningInstructionsEnum;
17+
import java.util.HashMap;
18+
import java.util.Map;
19+
import java.util.UUID;
20+
import org.databiosphere.workspacedataservice.workspacemanager.HttpWorkspaceManagerClientFactory;
21+
import org.databiosphere.workspacedataservice.workspacemanager.WorkspaceManagerClientFactory;
22+
import org.databiosphere.workspacedataservice.workspacemanager.WorkspaceManagerDao;
23+
import org.databiosphere.workspacedataservice.workspacemanager.WorkspaceManagerException;
24+
import org.junit.jupiter.api.BeforeEach;
25+
import org.junit.jupiter.api.Tag;
26+
import org.junit.jupiter.api.Test;
27+
import org.junit.jupiter.api.extension.ExtendWith;
28+
import org.springframework.mock.web.MockHttpServletRequest;
29+
import org.springframework.web.context.request.RequestContextHolder;
30+
import org.springframework.web.context.request.ServletRequestAttributes;
31+
32+
@Tag("pact-test")
33+
@ExtendWith(PactConsumerTestExt.class)
34+
public class WsmPactTest {
35+
// copied from DslPart.UUID_REGEX, used to configure Pact to accept a wildcard UUID as the
36+
// workspaceId path param
37+
private static final String UUID_REGEX_PATTERN =
38+
"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
39+
40+
// hardcoded to something vaguely human-readable to prevent churn in pactfiles
41+
private static final UUID WORKSPACE_UUID =
42+
UUID.fromString("facade00-0000-4000-a000-000000000000");
43+
44+
// hardcoded to something vaguely human-readable to prevent churn in pactfiles
45+
private static final UUID SNAPSHOT_UUID = UUID.fromString("decade00-0000-4000-a000-000000000000");
46+
private static final String SNAPSHOT_NAME = "hardcodedSnapshotName";
47+
private static final String SNAPSHOT_CREATOR_EMAIL = "[email protected]";
48+
49+
@BeforeEach
50+
void setUp() {
51+
// Without this setup, the HttpClient throws a "No thread-bound request found" error
52+
RequestContextHolder.setRequestAttributes(
53+
new ServletRequestAttributes(new MockHttpServletRequest()));
54+
}
55+
56+
private String snapshotPath(String workspaceIdPart) {
57+
return String.format(
58+
"/api/workspaces/v1/%s/resources/referenced/datarepo/snapshots", workspaceIdPart);
59+
}
60+
61+
@Pact(consumer = "terra-workspace-data-service", provider = "terra-workspace-manager")
62+
RequestResponsePact createDataRepoSnapshotReferenceSuccess(PactDslWithProvider builder) {
63+
return builder
64+
.given("a workspace with the given id exists", Map.of("id", WORKSPACE_UUID.toString()))
65+
.given("authenticated with the given email", Map.of("email", SNAPSHOT_CREATOR_EMAIL))
66+
.given("policies allowing snapshot reference creation")
67+
.uponReceiving("a request to create a snapshot reference")
68+
.matchPath(snapshotPath(UUID_REGEX_PATTERN), snapshotPath(WORKSPACE_UUID.toString()))
69+
.method("POST")
70+
.headers(contentTypeJson())
71+
.body(createSnapshotReferenceBody(SNAPSHOT_NAME))
72+
.willRespondWith()
73+
.status(200) // ok
74+
.headers(contentTypeJson())
75+
.body(
76+
newJsonBody(
77+
body -> {
78+
// put expectations here if we ever start reading fields in the code under
79+
// test
80+
})
81+
.build())
82+
.toPact();
83+
}
84+
85+
private String conditions(String... conditions) {
86+
return String.join(" and ", conditions);
87+
}
88+
89+
@Pact(consumer = "terra-workspace-data-service", provider = "terra-workspace-manager")
90+
RequestResponsePact createDataRepoSnapshotReferencePolicyConflict(PactDslWithProvider builder) {
91+
return builder
92+
.given("a workspace with the given id exists", Map.of("id", WORKSPACE_UUID.toString()))
93+
.given("authenticated with the given email", Map.of("email", SNAPSHOT_CREATOR_EMAIL))
94+
.given("policies preventing snapshot reference creation")
95+
.uponReceiving("a request to create a snapshot reference")
96+
.matchPath(snapshotPath(UUID_REGEX_PATTERN), snapshotPath(WORKSPACE_UUID.toString()))
97+
.method("POST")
98+
.headers(contentTypeJson())
99+
.body(createSnapshotReferenceBody(SNAPSHOT_NAME))
100+
.willRespondWith()
101+
.status(409) // conflict
102+
.headers(contentTypeJson())
103+
.body(
104+
newJsonBody(
105+
body ->
106+
body.stringMatcher(
107+
"message", "^(.*)policy conflict(.*)$", "unexpected policy conflict"))
108+
.build())
109+
.toPact();
110+
}
111+
112+
@Test
113+
@PactTestFor(
114+
pactMethod = "createDataRepoSnapshotReferenceSuccess",
115+
pactVersion = PactSpecVersion.V3)
116+
void testCreateDataRepoSnapshotReferenceSuccess(MockServer mockServer) {
117+
var wsmDao = buildWsmDao(mockServer);
118+
var snapshotModel = buildSnapshotModel();
119+
120+
assertDoesNotThrow(() -> wsmDao.createDataRepoSnapshotReference(snapshotModel));
121+
}
122+
123+
@Test
124+
@PactTestFor(
125+
pactMethod = "createDataRepoSnapshotReferencePolicyConflict",
126+
pactVersion = PactSpecVersion.V3)
127+
void testCreateDataRepoSnapshotReferenceConflict(MockServer mockServer) {
128+
var wsmDao = buildWsmDao(mockServer);
129+
var snapshotModel = buildSnapshotModel();
130+
131+
assertThrows(
132+
WorkspaceManagerException.class,
133+
() -> wsmDao.createDataRepoSnapshotReference(snapshotModel));
134+
}
135+
136+
private SnapshotModel buildSnapshotModel() {
137+
return new SnapshotModel().id(SNAPSHOT_UUID).name(SNAPSHOT_NAME);
138+
}
139+
140+
private WorkspaceManagerDao buildWsmDao(MockServer mockServer) {
141+
WorkspaceManagerClientFactory clientFactory =
142+
new HttpWorkspaceManagerClientFactory(mockServer.getUrl());
143+
return new WorkspaceManagerDao(clientFactory, WORKSPACE_UUID.toString());
144+
}
145+
146+
private DslPart createSnapshotReferenceBody(String snapshotName) {
147+
// metadata.name is a composite of <snapshotName>_<timestamp>
148+
String nameFormatString = String.format("'%s'_yyyyMMddHHmmss", snapshotName);
149+
150+
return newJsonBody(
151+
body -> {
152+
body.object(
153+
"snapshot",
154+
snapshot -> {
155+
snapshot.stringValue("instanceName", "terra");
156+
snapshot.uuid("snapshot");
157+
});
158+
body.object(
159+
"metadata",
160+
metadata -> {
161+
metadata.stringValue(
162+
"cloningInstructions", CloningInstructionsEnum.REFERENCE.toString());
163+
metadata.datetime("name", nameFormatString);
164+
});
165+
})
166+
.build();
167+
}
168+
169+
private Map<String, String> contentTypeJson() {
170+
Map<String, String> headers = new HashMap<>();
171+
// pact will automatically assume an expected Content-Type of "application/json; charset=UTF-8"
172+
// unless we explicitly tell it otherwise
173+
headers.put("Content-Type", "application/json");
174+
return headers;
175+
}
176+
}

0 commit comments

Comments
 (0)