Skip to content

Commit f1d3011

Browse files
Fixes created by tests
Signed-off-by: Darshit Chanpura <[email protected]>
1 parent 7a868cb commit f1d3011

File tree

2 files changed

+348
-3
lines changed

2 files changed

+348
-3
lines changed

server/src/main/java/org/opensearch/accesscontrol/resources/CreatedBy.java

+63-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
package org.opensearch.accesscontrol.resources;
1010

1111
import org.opensearch.core.common.io.stream.NamedWriteable;
12+
import org.opensearch.core.common.io.stream.StreamInput;
13+
import org.opensearch.core.common.io.stream.StreamOutput;
1214
import org.opensearch.core.xcontent.ToXContentFragment;
15+
import org.opensearch.core.xcontent.XContentBuilder;
1316
import org.opensearch.core.xcontent.XContentParser;
1417

1518
import java.io.IOException;
@@ -20,10 +23,67 @@
2023
*
2124
* @opensearch.experimental
2225
*/
23-
public abstract class CreatedBy implements ToXContentFragment, NamedWriteable {
26+
public class CreatedBy implements ToXContentFragment, NamedWriteable {
27+
28+
private final String creatorType;
29+
private final String creator;
30+
31+
public CreatedBy(String creatorType, String creator) {
32+
this.creatorType = creatorType;
33+
this.creator = creator;
34+
}
35+
36+
public CreatedBy(StreamInput in) throws IOException {
37+
this.creatorType = in.readString();
38+
this.creator = in.readString();
39+
}
40+
41+
public String getCreator() {
42+
return creator;
43+
}
44+
45+
public String getCreatorType() {
46+
return creatorType;
47+
}
48+
49+
@Override
50+
public String toString() {
51+
return "CreatedBy {" + this.creatorType + "='" + this.creator + '\'' + '}';
52+
}
53+
54+
@Override
55+
public String getWriteableName() {
56+
return "created_by";
57+
}
58+
59+
@Override
60+
public void writeTo(StreamOutput out) throws IOException {
61+
out.writeString(creatorType);
62+
out.writeString(creator);
63+
}
64+
65+
@Override
66+
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
67+
return builder.startObject().field(creatorType, creator).endObject();
68+
}
2469

25-
// Non-default implementation provided by security plugin
2670
public static CreatedBy fromXContent(XContentParser parser) throws IOException {
27-
return null;
71+
String creator = null;
72+
String creatorType = null;
73+
XContentParser.Token token;
74+
75+
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
76+
if (token == XContentParser.Token.FIELD_NAME) {
77+
creatorType = parser.currentName();
78+
} else if (token == XContentParser.Token.VALUE_STRING) {
79+
creator = parser.text();
80+
}
81+
}
82+
83+
if (creator == null) {
84+
throw new IllegalArgumentException(creatorType + " is required");
85+
}
86+
87+
return new CreatedBy(creatorType, creator);
2888
}
2989
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*/
8+
9+
package org.opensearch.accesscontrol.resources;
10+
11+
import org.opensearch.common.io.stream.BytesStreamOutput;
12+
import org.opensearch.common.xcontent.XContentFactory;
13+
import org.opensearch.common.xcontent.json.JsonXContent;
14+
import org.opensearch.core.common.io.stream.StreamInput;
15+
import org.opensearch.core.common.io.stream.StreamOutput;
16+
import org.opensearch.core.xcontent.XContentBuilder;
17+
import org.opensearch.core.xcontent.XContentParser;
18+
import org.opensearch.test.OpenSearchTestCase;
19+
import org.hamcrest.MatcherAssert;
20+
21+
import java.io.IOException;
22+
23+
import static org.hamcrest.Matchers.equalTo;
24+
import static org.hamcrest.Matchers.greaterThan;
25+
import static org.hamcrest.Matchers.is;
26+
import static org.hamcrest.Matchers.notNullValue;
27+
import static org.hamcrest.Matchers.nullValue;
28+
import static org.mockito.Mockito.mock;
29+
import static org.mockito.Mockito.when;
30+
31+
public class CreatedByTests extends OpenSearchTestCase {
32+
33+
private static final String CREATOR_TYPE = "user";
34+
35+
public void testCreatedByConstructorWithValidUser() {
36+
String expectedUser = "testUser";
37+
CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, expectedUser);
38+
39+
MatcherAssert.assertThat(expectedUser, is(equalTo(createdBy.getCreator())));
40+
}
41+
42+
public void testCreatedByFromStreamInput() throws IOException {
43+
String expectedUser = "testUser";
44+
45+
try (BytesStreamOutput out = new BytesStreamOutput()) {
46+
out.writeString(CREATOR_TYPE);
47+
out.writeString(expectedUser);
48+
49+
StreamInput in = out.bytes().streamInput();
50+
51+
CreatedBy createdBy = new CreatedBy(in);
52+
53+
MatcherAssert.assertThat(expectedUser, is(equalTo(createdBy.getCreator())));
54+
}
55+
}
56+
57+
public void testCreatedByWithEmptyStreamInput() throws IOException {
58+
59+
try (StreamInput mockStreamInput = mock(StreamInput.class)) {
60+
when(mockStreamInput.readString()).thenThrow(new IOException("EOF"));
61+
62+
assertThrows(IOException.class, () -> new CreatedBy(mockStreamInput));
63+
}
64+
}
65+
66+
public void testCreatedByWithEmptyUser() {
67+
68+
CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, "");
69+
MatcherAssert.assertThat("", equalTo(createdBy.getCreator()));
70+
}
71+
72+
public void testCreatedByWithIOException() throws IOException {
73+
74+
try (StreamInput mockStreamInput = mock(StreamInput.class)) {
75+
when(mockStreamInput.readString()).thenThrow(new IOException("Test IOException"));
76+
77+
assertThrows(IOException.class, () -> new CreatedBy(mockStreamInput));
78+
}
79+
}
80+
81+
public void testCreatedByWithLongUsername() {
82+
String longUsername = "a".repeat(10000);
83+
CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, longUsername);
84+
MatcherAssert.assertThat(longUsername, equalTo(createdBy.getCreator()));
85+
}
86+
87+
public void testCreatedByWithUnicodeCharacters() {
88+
String unicodeUsername = "用户こんにちは";
89+
CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, unicodeUsername);
90+
MatcherAssert.assertThat(unicodeUsername, equalTo(createdBy.getCreator()));
91+
}
92+
93+
public void testFromXContentThrowsExceptionWhenUserFieldIsMissing() throws IOException {
94+
String emptyJson = "{}";
95+
IllegalArgumentException exception;
96+
try (XContentParser parser = JsonXContent.jsonXContent.createParser(null, null, emptyJson)) {
97+
98+
exception = assertThrows(IllegalArgumentException.class, () -> CreatedBy.fromXContent(parser));
99+
}
100+
101+
MatcherAssert.assertThat("null is required", equalTo(exception.getMessage()));
102+
}
103+
104+
public void testFromXContentWithEmptyInput() throws IOException {
105+
String emptyJson = "{}";
106+
try (XContentParser parser = JsonXContent.jsonXContent.createParser(null, null, emptyJson)) {
107+
108+
assertThrows(IllegalArgumentException.class, () -> CreatedBy.fromXContent(parser));
109+
}
110+
}
111+
112+
public void testFromXContentWithExtraFields() throws IOException {
113+
String jsonWithExtraFields = "{\"user\": \"testUser\", \"extraField\": \"value\"}";
114+
XContentParser parser = JsonXContent.jsonXContent.createParser(null, null, jsonWithExtraFields);
115+
116+
CreatedBy.fromXContent(parser);
117+
}
118+
119+
public void testFromXContentWithIncorrectFieldType() throws IOException {
120+
String jsonWithIncorrectType = "{\"user\": 12345}";
121+
try (XContentParser parser = JsonXContent.jsonXContent.createParser(null, null, jsonWithIncorrectType)) {
122+
123+
assertThrows(IllegalArgumentException.class, () -> CreatedBy.fromXContent(parser));
124+
}
125+
}
126+
127+
public void testFromXContentWithEmptyUser() throws IOException {
128+
String emptyJson = "{\"" + CREATOR_TYPE + "\": \"\" }";
129+
CreatedBy createdBy;
130+
try (XContentParser parser = JsonXContent.jsonXContent.createParser(null, null, emptyJson)) {
131+
parser.nextToken();
132+
133+
createdBy = CreatedBy.fromXContent(parser);
134+
}
135+
136+
MatcherAssert.assertThat(CREATOR_TYPE, equalTo(createdBy.getCreatorType()));
137+
MatcherAssert.assertThat("", equalTo(createdBy.getCreator()));
138+
}
139+
140+
public void testFromXContentWithNullUserValue() throws IOException {
141+
String jsonWithNullUser = "{\"user\": null}";
142+
try (XContentParser parser = JsonXContent.jsonXContent.createParser(null, null, jsonWithNullUser)) {
143+
144+
assertThrows(IllegalArgumentException.class, () -> CreatedBy.fromXContent(parser));
145+
}
146+
}
147+
148+
public void testFromXContentWithValidUser() throws IOException {
149+
String json = "{\"user\":\"testUser\"}";
150+
XContentParser parser = JsonXContent.jsonXContent.createParser(null, null, json);
151+
152+
CreatedBy createdBy = CreatedBy.fromXContent(parser);
153+
154+
MatcherAssert.assertThat(createdBy, notNullValue());
155+
MatcherAssert.assertThat("testUser", equalTo(createdBy.getCreator()));
156+
}
157+
158+
public void testGetCreatorReturnsCorrectValue() {
159+
String expectedUser = "testUser";
160+
CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, expectedUser);
161+
162+
String actualUser = createdBy.getCreator();
163+
164+
MatcherAssert.assertThat(expectedUser, equalTo(actualUser));
165+
}
166+
167+
public void testGetCreatorWithNullString() {
168+
169+
CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, null);
170+
MatcherAssert.assertThat(createdBy.getCreator(), nullValue());
171+
}
172+
173+
public void testGetWriteableNameReturnsCorrectString() {
174+
CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, "testUser");
175+
MatcherAssert.assertThat("created_by", equalTo(createdBy.getWriteableName()));
176+
}
177+
178+
public void testToStringWithEmptyUser() {
179+
CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, "");
180+
String result = createdBy.toString();
181+
MatcherAssert.assertThat("CreatedBy {user=''}", equalTo(result));
182+
}
183+
184+
public void testToStringWithNullUser() {
185+
CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, (String) null);
186+
String result = createdBy.toString();
187+
MatcherAssert.assertThat("CreatedBy {user='null'}", equalTo(result));
188+
}
189+
190+
public void testToStringWithLongUserName() {
191+
192+
String longUserName = "a".repeat(1000);
193+
CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, longUserName);
194+
String result = createdBy.toString();
195+
MatcherAssert.assertThat(result.startsWith("CreatedBy {user='"), is(true));
196+
MatcherAssert.assertThat(result.endsWith("'}"), is(true));
197+
MatcherAssert.assertThat(1019, equalTo(result.length()));
198+
}
199+
200+
public void testToXContentWithEmptyUser() throws IOException {
201+
CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, "");
202+
XContentBuilder builder = JsonXContent.contentBuilder();
203+
204+
createdBy.toXContent(builder, null);
205+
String result = builder.toString();
206+
MatcherAssert.assertThat("{\"user\":\"\"}", equalTo(result));
207+
}
208+
209+
public void testWriteToWithExceptionInStreamOutput() throws IOException {
210+
CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, "user1");
211+
try (StreamOutput failingOutput = new StreamOutput() {
212+
@Override
213+
public void writeByte(byte b) throws IOException {
214+
throw new IOException("Simulated IO exception");
215+
}
216+
217+
@Override
218+
public void writeBytes(byte[] b, int offset, int length) throws IOException {
219+
throw new IOException("Simulated IO exception");
220+
}
221+
222+
@Override
223+
public void flush() throws IOException {
224+
225+
}
226+
227+
@Override
228+
public void close() throws IOException {
229+
230+
}
231+
232+
@Override
233+
public void reset() throws IOException {
234+
235+
}
236+
}) {
237+
238+
assertThrows(IOException.class, () -> createdBy.writeTo(failingOutput));
239+
}
240+
}
241+
242+
public void testWriteToWithLongUserName() throws IOException {
243+
String longUserName = "a".repeat(65536);
244+
CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, longUserName);
245+
BytesStreamOutput out = new BytesStreamOutput();
246+
createdBy.writeTo(out);
247+
MatcherAssert.assertThat(out.size(), greaterThan(65536));
248+
}
249+
250+
public void test_createdByToStringReturnsCorrectFormat() {
251+
String testUser = "testUser";
252+
CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, testUser);
253+
254+
String expected = "CreatedBy {user='" + testUser + "'}";
255+
String actual = createdBy.toString();
256+
257+
MatcherAssert.assertThat(expected, equalTo(actual));
258+
}
259+
260+
public void test_toXContent_serializesCorrectly() throws IOException {
261+
String expectedUser = "testUser";
262+
CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, expectedUser);
263+
XContentBuilder builder = XContentFactory.jsonBuilder();
264+
265+
createdBy.toXContent(builder, null);
266+
267+
String expectedJson = "{\"user\":\"testUser\"}";
268+
MatcherAssert.assertThat(expectedJson, equalTo(builder.toString()));
269+
}
270+
271+
public void test_writeTo_writesUserCorrectly() throws IOException {
272+
String expectedUser = "testUser";
273+
CreatedBy createdBy = new CreatedBy(CREATOR_TYPE, expectedUser);
274+
275+
BytesStreamOutput out = new BytesStreamOutput();
276+
createdBy.writeTo(out);
277+
278+
StreamInput in = out.bytes().streamInput();
279+
in.readString();
280+
String actualUser = in.readString();
281+
282+
MatcherAssert.assertThat(expectedUser, equalTo(actualUser));
283+
}
284+
285+
}

0 commit comments

Comments
 (0)