diff --git a/.gitignore b/.gitignore index a12d458..82d50ba 100644 --- a/.gitignore +++ b/.gitignore @@ -30,4 +30,5 @@ hs_err_pid* /.gradle/ /target/* .idea/* -.vscode/ \ No newline at end of file +.vscode/ +.claude/ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index e508bb8..089a87a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,62 +1,105 @@ -# Changelog -All notable changes to this project will be documented in this file. - -## [1.99.1] - -### Added - -- Add support for form features: - - `AccessControl` model - Represents permissions for view/edit access to forms - - `Form` model - Complete form definition including field definitions - - `FormField` abstract model – for all form field types - - `FormState` enum - Enumeration for form publishing states (NEW, PUBLISHED, UNPUBLISHED, OLD) - - `ChoiceFormField` model - Checkbox field with multiple selection support - - `DateFormField` model - Date input field with min/max validation - - `NumberFormField` model - Numeric field with range and decimal places - - `RadioFormField` model - Radio button field for single selection - - `StringFormField` model - Short text input field (max 255 characters) - - `TextFormField` model - Long text field supporting HTML content - - `TimeFormField` model - Time input field storing millisecond values - -### Changed - -- Enhanced `FormInfo` model with additional properties: - - Added `formState` property for tracking publishing status - - Added `accessControl` property for permission management - - Added `tags` property for form categorization - - Added `iconId` property for form visual identification - -## [1.99.0] -- switch from rspace-os-parent to rspace-parent as parent pom - -## [1.98.1] - -### Added -- Introduced support for document: - - `MoveRequest` model - -### Changed -- Upgrade dependency: lombok 1.18.42. - -## [1.98.0] - -### Added -- Introduced support for Inventory features: - - `Barcode` model - - `TagInfo` model - - `RecordInfo` model - - `SharedWith` model -- Added the ability to represent sharing mode, barcodes, and tags for Inventory. - -## [1.97.0] - -- Support newly added audit (activity) actions: DUPLICATE and RENAME -- Update list of possible audit (activity) domains - -## [1.95.0] -- Compile with java 17 -- Switch to using parent pom from rspace-os-parent project -- Change of produced artifact to from com.researchspace to com.github.rspace-os - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +# Changelog +All notable changes to this project will be documented in this file. + +## [1.100.0] + +### Breaking Changes + +- **`AbstractExportPost`** — `scope()` renamed to `getScopeAsString()`, `format()` renamed to `getFormatAsString()`. + Update any callers of the old method names. + +- **`ApiShareInfo.sharedItemName`** — field type corrected from `Long` to `String`. + Update any code that stores or passes `getSharedItemName()` as a `Long`. + +- **`FieldPut`** — locally-shadowed `content` field removed; `FieldPut` now inherits `content` from `FieldPost`. + The two-arg constructor `FieldPut(String content, Long id)` is preserved so existing callers still compile. + However, `equals()`/`hashCode()` no longer compare two separate `content` fields, and any code that set + the shadowed field via reflection must switch to the inherited field. + +- **`ActivitySearchResult`, `DocumentSearchResult`, `FileSearchResult`, `FormSearchResult`, `ShareSearchResult`** — + changed from `@Value` (immutable, all-args constructor) to `@Data @NoArgsConstructor` (mutable, no all-args constructor). + These are response POJOs and should not be constructed directly, but any code using the `@Value`-generated + constructor will no longer compile. + +- **`User`** — replaced `@Value @NoArgsConstructor` with `@Data @NoArgsConstructor`. + Any code using positional construction (`new User(id, username, …)`) will no longer compile. + +- **`ISO8601DateSerialiser`** — dates are now always serialised in UTC (previously used the JVM default timezone). + A `Date` value whose local-timezone calendar date differs from its UTC date will now serialise differently. + Ensure all `Date` values passed to `DateFormField` represent midnight UTC if exact date identity matters. + +### Added + +- `UserInfo` — full user information returned by the sysadmin user-listing endpoint. +- `UserSearchResult` — paginated wrapper for `UserInfo` lists. +- `GroupSearchResult` — paginated wrapper for `GroupInfo` lists returned by the sysadmin group-listing endpoint. +- `SharePermissionUpdate` — request body for `PUT /share` (update permission of an existing share). +- `DocumentShares` — response for `GET /share/document/{id}`; contains `directShares` and `notebookShares` as `List`. +- `DocumentShareEntry` — a single entry within a `DocumentShares` response. + +### Fixed + +- `@JsonIgnoreProperties(ignoreUnknown = true)` added to all response POJOs. Prevents `UnrecognizedPropertyException` + when the server adds new fields in future releases. +- `ISO8601DateSerialiser` — replaced per-call `SimpleDateFormat` with a thread-safe static `DateTimeFormatter`. +- Removed stale swagger-codegen `DO NOT EDIT` headers from 12 source files. + +## [1.99.1] + +### Added + +- Add support for form features: + - `AccessControl` model - Represents permissions for view/edit access to forms + - `Form` model - Complete form definition including field definitions + - `FormField` abstract model – for all form field types + - `FormState` enum - Enumeration for form publishing states (NEW, PUBLISHED, UNPUBLISHED, OLD) + - `ChoiceFormField` model - Checkbox field with multiple selection support + - `DateFormField` model - Date input field with min/max validation + - `NumberFormField` model - Numeric field with range and decimal places + - `RadioFormField` model - Radio button field for single selection + - `StringFormField` model - Short text input field (max 255 characters) + - `TextFormField` model - Long text field supporting HTML content + - `TimeFormField` model - Time input field storing millisecond values + +### Changed + +- Enhanced `FormInfo` model with additional properties: + - Added `formState` property for tracking publishing status + - Added `accessControl` property for permission management + - Added `tags` property for form categorization + - Added `iconId` property for form visual identification + +## [1.99.0] +- switch from rspace-os-parent to rspace-parent as parent pom + +## [1.98.1] + +### Added +- Introduced support for a document: + - `MoveRequest` model + +### Changed +- Upgrade dependency: lombok 1.18.42. + +## [1.98.0] + +### Added +- Introduced support for Inventory features: + - `Barcode` model + - `TagInfo` model + - `RecordInfo` model + - `SharedWith` model +- Added the ability to represent sharing mode, barcodes, and tags for Inventory. + +## [1.97.0] + +- Support newly added audit (activity) actions: DUPLICATE and RENAME +- Update list of possible audit (activity) domains + +## [1.95.0] +- Compile with java 17 +- Switch to using parent pom from rspace-os-parent project +- Change of produced artifact to from com.researchspace to com.github.rspace-os + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..cd764ea --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,93 @@ +# rspace-client-java-model + +Pure POJO library. No HTTP. No Spring. No business logic. +Provides request and response model classes for the RSpace REST API, consumed by: +- `rspace-api-acceptance` — the API client and acceptance test repo +- `rspace-playwright-java` — the UI E2E test framework (via `ApiUtils`) + +**Cross-repo rule:** Any change to this library that renames, removes, or changes the type of a field or method must also be checked (and fixed if broken) in both `rspace-api-acceptance` and `rspace-playwright-java` before the PR is merged. + +--- + +## Module layout + +``` +src/main/java/ + com.researchspace.api.clientmodel/ ← ELN request + response POJOs + com.researchspace.api.clientmodel.inventory/ ← Inventory base types only + com.researchspace.api.jackson/ ← Custom Jackson serialisers + +src/test/java/ + com.researchspace.api.clientmodel/ ← Unit tests: serialisation + builder contracts +``` + +### Inheritance hierarchy — never instantiate base classes directly + +``` +Linkable ← _links list + getLinkByType() + └── PaginatedResultList ← totalHits, pageNumber, pageSize + └── IdentifiableNameable ← id, globalId, name + └── DocumentInfo ← created, lastModified, tags, form, owner, parentFolderId + └── Document ← fields: List + └── FormInfo ← stableId, version, formState, accessControl, tags + └── Form ← fields: List + └── GroupInfo ← type, sharedFolderId, members + └── ApiFile ← contentType, size, caption, created, version + └── RecordInfo (inventory) ← description, tags, sharingMode, barcodes +``` + +## Testing rules + +All tests use **JUnit 5** (`org.junit.jupiter.api.Test`). Do not use JUnit 4. + +### Two test patterns + +**JSON fixture roundtrip** (via `AbstractModelTest`) — use for response POJOs: +```java +MyType result = readFileToClass(new File("src/test/resources/MyType.json"), MyType.class); +assertEquals("expectedValue", result.getSomeField()); +``` + +**Serialisation roundtrip** (inline `ObjectMapper`) — use for request POJOs and serialisation contracts: +```java +ObjectMapper om = new ObjectMapper(); +String json = om.writeValueAsString(myObject); +MyType deserialised = om.readValue(json, MyType.class); +assertEquals(expected, deserialised.getSomeField()); +``` + +### Every new POJO needs at least one test + +Minimum: deserialise from a representative JSON fixture and assert on the fields. If the class has builder methods (`addField()`, `appendContent()`), test those too. + +### JSON fixtures + +Location: `src/test/resources/`. Every `PaginatedResultList` fixture must include `totalHits`, `pageNumber`, and `pageSize`. + +Existing fixtures: `Document.json`, `DocumentSearchResult.json`, `DocumentSearchQuery.json`, `ActivitySearchResult.json`, `FileSearchResult.json`, `File.json`, `Folder.json`, `FormSearchResult.json`, `Form.json`, `FolderTreeItemListing.json`, `GroupSearchResult.json`, `User.json`, `UserInfo.json`, `UserSearchResult.json`, `completedJob.json`. + +--- + +## Adding a new class — checklist + +1. Decide which category: response POJO, request POJO, base class, or inventory base +2. Choose Lombok annotations from the taxonomy table — do not invent new combinations +3. Add `@JsonIgnoreProperties(ignoreUnknown = true)` if it is a response POJO +4. Add a JSON fixture in `src/test/resources/` (or use a serialisation roundtrip test for request POJOs) +5. Write a unit test asserting on fields +6. Verify field names against the server source before adding fields not in the current Swagger: `https://github.com/rspace-os/rspace-web/tree/main/src/main/java/com/researchspace/api/v1` +7. Check `rspace-api-acceptance` and `rspace-playwright-java` for any callers affected by the change + +--- + +## Constraints + +- No Spring, RestTemplate, or HTTP dependencies in this module +- No concrete inventory response types (`RSSample`, `RSInvContainer`, etc.) — those belong in `rspace-api-acceptance` +- No `@Value` on classes that Jackson needs to deserialise +- No swagger-codegen `DO NOT EDIT` header comments — those files are manually maintained +- No `jakarta.validation` — use `javax.validation` only +- No new field on a response POJO without a test that verifies it deserialises correctly +- No new Lombok combinations not in the taxonomy table + +--- diff --git a/pom.xml b/pom.xml index 628e493..deacf73 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 rspace-client-java-model - 1.99.1 + 1.100.0 rspace-client-java-model com.github.rspace-os diff --git a/src/main/java/com/researchspace/api/clientmodel/AbstractExportPost.java b/src/main/java/com/researchspace/api/clientmodel/AbstractExportPost.java index e11721d..265b551 100644 --- a/src/main/java/com/researchspace/api/clientmodel/AbstractExportPost.java +++ b/src/main/java/com/researchspace/api/clientmodel/AbstractExportPost.java @@ -1,5 +1,6 @@ package com.researchspace.api.clientmodel; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -12,11 +13,13 @@ public class AbstractExportPost { private ExportScope scope = ExportScope.USER; private ExportFormat format = ExportFormat.HTML; - public String scope () { + @JsonIgnore + public String getScopeAsString() { return scope.name().toLowerCase(); } - - public String format () { + + @JsonIgnore + public String getFormatAsString() { return format.name().toLowerCase(); } diff --git a/src/main/java/com/researchspace/api/clientmodel/Activity.java b/src/main/java/com/researchspace/api/clientmodel/Activity.java index 4b6d82c..b1cac6f 100644 --- a/src/main/java/com/researchspace/api/clientmodel/Activity.java +++ b/src/main/java/com/researchspace/api/clientmodel/Activity.java @@ -3,6 +3,7 @@ import java.util.Date; import java.util.Map; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; import lombok.EqualsAndHashCode; /** @@ -12,6 +13,7 @@ */ @Data @EqualsAndHashCode(of={"timestamp", "username", "domain","action"}) +@JsonIgnoreProperties(ignoreUnknown = true) public class Activity { private Date timestamp; diff --git a/src/main/java/com/researchspace/api/clientmodel/ActivitySearchResult.java b/src/main/java/com/researchspace/api/clientmodel/ActivitySearchResult.java index 28261fd..8d5becd 100644 --- a/src/main/java/com/researchspace/api/clientmodel/ActivitySearchResult.java +++ b/src/main/java/com/researchspace/api/clientmodel/ActivitySearchResult.java @@ -4,16 +4,20 @@ import java.util.ArrayList; import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; import lombok.ToString; -import lombok.Value; /** * ActivitySearchResults */ -@Value -@EqualsAndHashCode(callSuper=true) -@ToString(callSuper=true) +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) public class ActivitySearchResult extends PaginatedResultList { private List activities = new ArrayList<>(); diff --git a/src/main/java/com/researchspace/api/clientmodel/ApiFile.java b/src/main/java/com/researchspace/api/clientmodel/ApiFile.java index 0d9ed5d..5f436f0 100644 --- a/src/main/java/com/researchspace/api/clientmodel/ApiFile.java +++ b/src/main/java/com/researchspace/api/clientmodel/ApiFile.java @@ -1,27 +1,3 @@ -/** - * RSpace API - * Access your RSpace documents programmatically. All requests require authentication using an API key set as the value of the header `RSpace-API-Key`. - * - * OpenAPI spec version: 0.1 - * Contact: support@researchspace.com - * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git - * Do not edit the class manually. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package com.researchspace.api.clientmodel; import java.util.Date; diff --git a/src/main/java/com/researchspace/api/clientmodel/ApiShareInfo.java b/src/main/java/com/researchspace/api/clientmodel/ApiShareInfo.java index 1baf4cb..5df4ddd 100644 --- a/src/main/java/com/researchspace/api/clientmodel/ApiShareInfo.java +++ b/src/main/java/com/researchspace/api/clientmodel/ApiShareInfo.java @@ -2,6 +2,7 @@ +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @@ -13,10 +14,14 @@ @Data @EqualsAndHashCode(callSuper = false) @NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) public class ApiShareInfo { - - private Long id, sharedItemId,sharedItemName; - private String sharedTargetType, permission; + + private Long id; + private Long sharedItemId; + private String sharedItemName; + private String sharedTargetType; + private String permission; } diff --git a/src/main/java/com/researchspace/api/clientmodel/ApiSharingResult.java b/src/main/java/com/researchspace/api/clientmodel/ApiSharingResult.java index 306a570..f5385ce 100644 --- a/src/main/java/com/researchspace/api/clientmodel/ApiSharingResult.java +++ b/src/main/java/com/researchspace/api/clientmodel/ApiSharingResult.java @@ -2,6 +2,7 @@ import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @@ -9,6 +10,7 @@ @Data @EqualsAndHashCode(callSuper = false) @NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) public class ApiSharingResult { diff --git a/src/main/java/com/researchspace/api/clientmodel/DocumentInfo.java b/src/main/java/com/researchspace/api/clientmodel/DocumentInfo.java index 7922cb4..77c8985 100644 --- a/src/main/java/com/researchspace/api/clientmodel/DocumentInfo.java +++ b/src/main/java/com/researchspace/api/clientmodel/DocumentInfo.java @@ -1,27 +1,3 @@ -/** - * RSpace API - * Access your RSpace documents programmatically. All requests require authentication using an API key set as the value of the header `RSpace-API-Key`. - * - * OpenAPI spec version: 0.1 - * Contact: support@researchspace.com - * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git - * Do not edit the class manually. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package com.researchspace.api.clientmodel; import java.util.Date; diff --git a/src/main/java/com/researchspace/api/clientmodel/DocumentSearchResult.java b/src/main/java/com/researchspace/api/clientmodel/DocumentSearchResult.java index f98bb72..3f47726 100644 --- a/src/main/java/com/researchspace/api/clientmodel/DocumentSearchResult.java +++ b/src/main/java/com/researchspace/api/clientmodel/DocumentSearchResult.java @@ -1,44 +1,24 @@ -/** - * RSpace API - * Access your RSpace documents programmatically. All requests require authentication using an API key set as the value of the header `RSpace-API-Key`. - * - * OpenAPI spec version: 0.1 - * Contact: support@researchspace.com - * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git - * Do not edit the class manually. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package com.researchspace.api.clientmodel; import java.util.ArrayList; import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; import lombok.ToString; -import lombok.Value; /** * DocumentSearchResults */ -@Value -@EqualsAndHashCode(callSuper=true) -@ToString(callSuper=true) +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) public class DocumentSearchResult extends PaginatedResultList { - List documents = new ArrayList<>(); + private List documents = new ArrayList<>(); } diff --git a/src/main/java/com/researchspace/api/clientmodel/DocumentShareEntry.java b/src/main/java/com/researchspace/api/clientmodel/DocumentShareEntry.java new file mode 100644 index 0000000..88dea6c --- /dev/null +++ b/src/main/java/com/researchspace/api/clientmodel/DocumentShareEntry.java @@ -0,0 +1,26 @@ +package com.researchspace.api.clientmodel; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * A single share entry within a {@link DocumentShares} response. + */ +@Data +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class DocumentShareEntry { + + private Long shareId; + private Long sharerId; + private String sharerName; + private Long recipientId; + private String recipientName; + private String recipientType; + private String permission; + private Long parentId; + private String path; + private Long grandparentId; + +} diff --git a/src/main/java/com/researchspace/api/clientmodel/DocumentShares.java b/src/main/java/com/researchspace/api/clientmodel/DocumentShares.java new file mode 100644 index 0000000..9cce002 --- /dev/null +++ b/src/main/java/com/researchspace/api/clientmodel/DocumentShares.java @@ -0,0 +1,23 @@ +package com.researchspace.api.clientmodel; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +/** + * Response for GET /share/document/{id} — all shares for a document, notebook or snippet. + */ +@Data +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class DocumentShares { + + private Long sharedDocId; + private String sharedDocName; + private List directShares = new ArrayList<>(); + private List notebookShares = new ArrayList<>(); + +} diff --git a/src/main/java/com/researchspace/api/clientmodel/ExportJob.java b/src/main/java/com/researchspace/api/clientmodel/ExportJob.java index fe1616c..5498e7c 100644 --- a/src/main/java/com/researchspace/api/clientmodel/ExportJob.java +++ b/src/main/java/com/researchspace/api/clientmodel/ExportJob.java @@ -1,5 +1,6 @@ package com.researchspace.api.clientmodel; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; import lombok.EqualsAndHashCode; /** @@ -9,6 +10,7 @@ */ @Data @EqualsAndHashCode(callSuper=true) +@JsonIgnoreProperties(ignoreUnknown = true) public class ExportJob extends Job { private ExportJobResult result; diff --git a/src/main/java/com/researchspace/api/clientmodel/ExportJobResult.java b/src/main/java/com/researchspace/api/clientmodel/ExportJobResult.java index 4169c1f..36d3154 100644 --- a/src/main/java/com/researchspace/api/clientmodel/ExportJobResult.java +++ b/src/main/java/com/researchspace/api/clientmodel/ExportJobResult.java @@ -2,9 +2,8 @@ import java.util.Date; -import lombok.AccessLevel; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; -import lombok.Setter; /** * An export job result @@ -13,6 +12,7 @@ * */ @Data +@JsonIgnoreProperties(ignoreUnknown = true) public class ExportJobResult implements Result { private String checksum; diff --git a/src/main/java/com/researchspace/api/clientmodel/Field.java b/src/main/java/com/researchspace/api/clientmodel/Field.java index d2903f4..7f46d2b 100644 --- a/src/main/java/com/researchspace/api/clientmodel/Field.java +++ b/src/main/java/com/researchspace/api/clientmodel/Field.java @@ -1,27 +1,3 @@ -/** - * RSpace API - * Access your RSpace documents programmatically. All requests require authentication using an API key set as the value of the header `RSpace-API-Key`. - * - * OpenAPI spec version: 0.1 - * Contact: support@researchspace.com - * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git - * Do not edit the class manually. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package com.researchspace.api.clientmodel; import java.util.ArrayList; diff --git a/src/main/java/com/researchspace/api/clientmodel/FieldPut.java b/src/main/java/com/researchspace/api/clientmodel/FieldPut.java index 4d497ad..a8028e6 100644 --- a/src/main/java/com/researchspace/api/clientmodel/FieldPut.java +++ b/src/main/java/com/researchspace/api/clientmodel/FieldPut.java @@ -1,29 +1,32 @@ package com.researchspace.api.clientmodel; -import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.NonNull; -@Data -@EqualsAndHashCode(callSuper=false) -@AllArgsConstructor -@NoArgsConstructor /** - * Extends FieldPost with a field Id property to specify the Field whose content is to be updated. - * @author rspace - * + * Extends FieldPost with a field Id property to specify the Field whose content is to be updated. */ +@Data +@EqualsAndHashCode(callSuper=true) +@NoArgsConstructor public class FieldPut extends FieldPost { - /** - * Optional content, can be empty. - */ - private String content=""; /** * Cannot be null */ @NonNull private Long id; + /** Constructor for updating a specific field by ID only (content left as default). */ + public FieldPut(Long id) { + this.id = id; + } + + /** Constructor for updating the content of a specific field by ID. */ + public FieldPut(String content, Long id) { + super(content); + this.id = id; + } + } diff --git a/src/main/java/com/researchspace/api/clientmodel/FileSearchResult.java b/src/main/java/com/researchspace/api/clientmodel/FileSearchResult.java index 2f51b2a..0989bdc 100644 --- a/src/main/java/com/researchspace/api/clientmodel/FileSearchResult.java +++ b/src/main/java/com/researchspace/api/clientmodel/FileSearchResult.java @@ -1,42 +1,24 @@ -/** - * RSpace API - * Access your RSpace documents programmatically. All requests require authentication using an API key set as the value of the header `RSpace-API-Key`. - * - * OpenAPI spec version: 0.1 - * Contact: support@researchspace.com - * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git - * Do not edit the class manually. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package com.researchspace.api.clientmodel; import java.util.ArrayList; import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; import lombok.EqualsAndHashCode; -import lombok.Value; +import lombok.NoArgsConstructor; +import lombok.ToString; /** * FileSearchResult */ -@Value -@EqualsAndHashCode(callSuper=true) +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) public class FileSearchResult extends PaginatedResultList { - private List files = new ArrayList(); + private List files = new ArrayList<>(); } diff --git a/src/main/java/com/researchspace/api/clientmodel/Folder.java b/src/main/java/com/researchspace/api/clientmodel/Folder.java index fc36300..2ab7349 100644 --- a/src/main/java/com/researchspace/api/clientmodel/Folder.java +++ b/src/main/java/com/researchspace/api/clientmodel/Folder.java @@ -1,27 +1,3 @@ -/** - * RSpace API - * Access your RSpace documents programmatically. All requests require authentication using an API key set as the value of the header `RSpace-API-Key`. - * - * OpenAPI spec version: 0.1 - * Contact: support@researchspace.com - * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git - * Do not edit the class manually. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package com.researchspace.api.clientmodel; import java.util.Date; diff --git a/src/main/java/com/researchspace/api/clientmodel/FolderTreeItemInfo.java b/src/main/java/com/researchspace/api/clientmodel/FolderTreeItemInfo.java index b39947a..4ad4751 100644 --- a/src/main/java/com/researchspace/api/clientmodel/FolderTreeItemInfo.java +++ b/src/main/java/com/researchspace/api/clientmodel/FolderTreeItemInfo.java @@ -2,31 +2,6 @@ import java.util.Date; -/** - * RSpace API - * Access your RSpace documents programmatically. All requests require authentication using an API key set as the value of the header `RSpace-API-Key`. - * - * OpenAPI spec version: 0.1 - * Contact: support@researchspace.com - * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git - * Do not edit the class manually. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; diff --git a/src/main/java/com/researchspace/api/clientmodel/FolderTreeItemListing.java b/src/main/java/com/researchspace/api/clientmodel/FolderTreeItemListing.java index 4fde3fa..16ba14c 100644 --- a/src/main/java/com/researchspace/api/clientmodel/FolderTreeItemListing.java +++ b/src/main/java/com/researchspace/api/clientmodel/FolderTreeItemListing.java @@ -3,13 +3,19 @@ import java.util.ArrayList; import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; @Data @EqualsAndHashCode(callSuper=true) +@ToString(callSuper=true) +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) public class FolderTreeItemListing extends PaginatedResultList { /** diff --git a/src/main/java/com/researchspace/api/clientmodel/FormSearchResult.java b/src/main/java/com/researchspace/api/clientmodel/FormSearchResult.java index 1093974..2ca3541 100644 --- a/src/main/java/com/researchspace/api/clientmodel/FormSearchResult.java +++ b/src/main/java/com/researchspace/api/clientmodel/FormSearchResult.java @@ -1,17 +1,21 @@ package com.researchspace.api.clientmodel; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import lombok.Value; - import java.util.ArrayList; import java.util.List; -@Value -@EqualsAndHashCode(callSuper=true) -@ToString(callSuper=true) +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) public class FormSearchResult extends PaginatedResultList { - List forms = new ArrayList<>(); + private List forms = new ArrayList<>(); } diff --git a/src/main/java/com/researchspace/api/clientmodel/GroupSearchResult.java b/src/main/java/com/researchspace/api/clientmodel/GroupSearchResult.java new file mode 100644 index 0000000..2079d4f --- /dev/null +++ b/src/main/java/com/researchspace/api/clientmodel/GroupSearchResult.java @@ -0,0 +1,22 @@ +package com.researchspace.api.clientmodel; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; + +import java.util.ArrayList; +import java.util.List; + +/** + * Paginated list of groups returned by the sysadmin group-listing endpoint. + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class GroupSearchResult extends PaginatedResultList { + private List groups = new ArrayList<>(); +} diff --git a/src/main/java/com/researchspace/api/clientmodel/IdentifiableNameable.java b/src/main/java/com/researchspace/api/clientmodel/IdentifiableNameable.java index 1fe534c..8b8701d 100644 --- a/src/main/java/com/researchspace/api/clientmodel/IdentifiableNameable.java +++ b/src/main/java/com/researchspace/api/clientmodel/IdentifiableNameable.java @@ -1,15 +1,15 @@ package com.researchspace.api.clientmodel; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.*; import lombok.experimental.SuperBuilder; -import java.util.List; - @Data @EqualsAndHashCode(callSuper = true) @NoArgsConstructor @AllArgsConstructor @SuperBuilder +@JsonIgnoreProperties(ignoreUnknown = true) public abstract class IdentifiableNameable extends Linkable { private Long id; private String globalId; diff --git a/src/main/java/com/researchspace/api/clientmodel/LinkItem.java b/src/main/java/com/researchspace/api/clientmodel/LinkItem.java index c1d5b9f..4e88d43 100644 --- a/src/main/java/com/researchspace/api/clientmodel/LinkItem.java +++ b/src/main/java/com/researchspace/api/clientmodel/LinkItem.java @@ -1,29 +1,6 @@ -/** - * RSpace API - * Access your RSpace documents programmatically. All requests require authentication using an API key set as the value of the header `RSpace-API-Key`. - * - * OpenAPI spec version: 0.1 - * Contact: support@researchspace.com - * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git - * Do not edit the class manually. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package com.researchspace.api.clientmodel; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -34,6 +11,7 @@ @Data @AllArgsConstructor @NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) public class LinkItem { public static final String NEXT_REL = "next"; diff --git a/src/main/java/com/researchspace/api/clientmodel/MoveRequest.java b/src/main/java/com/researchspace/api/clientmodel/MoveRequest.java index 134e299..90dc79e 100644 --- a/src/main/java/com/researchspace/api/clientmodel/MoveRequest.java +++ b/src/main/java/com/researchspace/api/clientmodel/MoveRequest.java @@ -1,14 +1,15 @@ package com.researchspace.api.clientmodel; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; /** - * Request to move a document or notebook to a target folder + * Request to move a document or notebook to a target folder. + * The server API field name is {@code docId}; the Java field is {@code recordId}. * - * @author rspac * @since 1.98.0 */ @Data @@ -17,6 +18,7 @@ @Builder public class MoveRequest { + @JsonProperty("docId") private Long recordId; private long sourceFolderId; private Long targetFolderId; diff --git a/src/main/java/com/researchspace/api/clientmodel/PaginatedResultList.java b/src/main/java/com/researchspace/api/clientmodel/PaginatedResultList.java index 3baa611..3e20388 100644 --- a/src/main/java/com/researchspace/api/clientmodel/PaginatedResultList.java +++ b/src/main/java/com/researchspace/api/clientmodel/PaginatedResultList.java @@ -1,27 +1,3 @@ -/** - * RSpace API - * Access your RSpace documents programmatically. All requests require authentication using an API key set as the value of the header `RSpace-API-Key`. - * - * OpenAPI spec version: 0.1 - * Contact: support@researchspace.com - * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git - * Do not edit the class manually. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package com.researchspace.api.clientmodel; import lombok.Data; @@ -35,7 +11,7 @@ @EqualsAndHashCode(callSuper=true) @ToString(callSuper=true) public abstract class PaginatedResultList extends Linkable { - - private Long totalHits = null; + private Long totalHits = null; private Integer pageNumber = null; + private Integer pageSize = null; } diff --git a/src/main/java/com/researchspace/api/clientmodel/SharePermissionUpdate.java b/src/main/java/com/researchspace/api/clientmodel/SharePermissionUpdate.java new file mode 100644 index 0000000..3b605a0 --- /dev/null +++ b/src/main/java/com/researchspace/api/clientmodel/SharePermissionUpdate.java @@ -0,0 +1,20 @@ +package com.researchspace.api.clientmodel; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Request body for PUT /share — updates the permission level of an existing share. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SharePermissionUpdate { + + private Long shareId; + private String permission; + +} diff --git a/src/main/java/com/researchspace/api/clientmodel/ShareSearchResult.java b/src/main/java/com/researchspace/api/clientmodel/ShareSearchResult.java index f467fb4..329ebd2 100644 --- a/src/main/java/com/researchspace/api/clientmodel/ShareSearchResult.java +++ b/src/main/java/com/researchspace/api/clientmodel/ShareSearchResult.java @@ -1,40 +1,22 @@ -/** - * RSpace API - * Access your RSpace documents programmatically. All requests require authentication using an API key set as the value of the header `RSpace-API-Key`. - * - * OpenAPI spec version: 0.1 - * Contact: support@researchspace.com - * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git - * Do not edit the class manually. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package com.researchspace.api.clientmodel; import java.util.ArrayList; import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; import lombok.EqualsAndHashCode; -import lombok.Value; +import lombok.NoArgsConstructor; +import lombok.ToString; /** - * FileSearchResult + * ShareSearchResult */ -@Value -@EqualsAndHashCode(callSuper=true) +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) public class ShareSearchResult extends PaginatedResultList { private List shares = new ArrayList<>(); diff --git a/src/main/java/com/researchspace/api/clientmodel/Status.java b/src/main/java/com/researchspace/api/clientmodel/Status.java index 1f0db51..e36a932 100644 --- a/src/main/java/com/researchspace/api/clientmodel/Status.java +++ b/src/main/java/com/researchspace/api/clientmodel/Status.java @@ -1,5 +1,6 @@ package com.researchspace.api.clientmodel; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -7,6 +8,7 @@ @Data @NoArgsConstructor @AllArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) public class Status { private String message; diff --git a/src/main/java/com/researchspace/api/clientmodel/User.java b/src/main/java/com/researchspace/api/clientmodel/User.java index 3576190..46bcf2a 100644 --- a/src/main/java/com/researchspace/api/clientmodel/User.java +++ b/src/main/java/com/researchspace/api/clientmodel/User.java @@ -1,45 +1,23 @@ -/** - * RSpace API - * Access your RSpace documents programmatically. All requests require authentication using an API key set as the value of the header `RSpace-API-Key`. - * - * OpenAPI spec version: 0.1 - * Contact: support@researchspace.com - * - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen.git - * Do not edit the class manually. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package com.researchspace.api.clientmodel; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; import lombok.NoArgsConstructor; -import lombok.Value; /** - * Representation of a User, this is read only as there is no API methods to alter user properties. + * Representation of a User. Read only — there are no API methods to alter user properties. * @since 1.1.0 */ -@Value +@Data @NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) public class User { - - private Long id = null; - private String username = null; - private String email = null; - private String firstName = null; - private String lastName = null; - private Long homeFolderId = null; + + private Long id; + private String username; + private String email; + private String firstName; + private String lastName; + private Long homeFolderId; } diff --git a/src/main/java/com/researchspace/api/clientmodel/UserGroupInfo.java b/src/main/java/com/researchspace/api/clientmodel/UserGroupInfo.java index f9bd919..89727c4 100644 --- a/src/main/java/com/researchspace/api/clientmodel/UserGroupInfo.java +++ b/src/main/java/com/researchspace/api/clientmodel/UserGroupInfo.java @@ -1,8 +1,12 @@ package com.researchspace.api.clientmodel; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Data; +import lombok.NoArgsConstructor; @Data +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) public class UserGroupInfo { private Long id; diff --git a/src/main/java/com/researchspace/api/clientmodel/UserInfo.java b/src/main/java/com/researchspace/api/clientmodel/UserInfo.java new file mode 100644 index 0000000..197a23c --- /dev/null +++ b/src/main/java/com/researchspace/api/clientmodel/UserInfo.java @@ -0,0 +1,33 @@ +package com.researchspace.api.clientmodel; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; + +/** + * Full user information as returned by the sysadmin user-listing endpoint. + *

+ * Note: {@code name} (inherited from {@link IdentifiableNameable}) is the display name of the user, + * while {@code username} is the unique login identifier used for authentication and API calls. + * Both fields are populated from the server response. + *

+ */ +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class UserInfo extends IdentifiableNameable { + + private String username; + private String email; + private String firstName; + private String lastName; + private UserRole role; + private String affiliation; + private boolean enabled; + private Long homeFolderId; + +} diff --git a/src/main/java/com/researchspace/api/clientmodel/UserSearchResult.java b/src/main/java/com/researchspace/api/clientmodel/UserSearchResult.java new file mode 100644 index 0000000..8f62199 --- /dev/null +++ b/src/main/java/com/researchspace/api/clientmodel/UserSearchResult.java @@ -0,0 +1,23 @@ +package com.researchspace.api.clientmodel; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; + +/** + * Paginated list of users returned by the sysadmin user-listing endpoint. + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class UserSearchResult extends PaginatedResultList { + private List users = new ArrayList<>(); + +} diff --git a/src/main/java/com/researchspace/api/jackson/ISO8601DateSerialiser.java b/src/main/java/com/researchspace/api/jackson/ISO8601DateSerialiser.java index 97bff5b..95da4a3 100644 --- a/src/main/java/com/researchspace/api/jackson/ISO8601DateSerialiser.java +++ b/src/main/java/com/researchspace/api/jackson/ISO8601DateSerialiser.java @@ -1,41 +1,40 @@ package com.researchspace.api.jackson; import java.io.IOException; -import java.text.SimpleDateFormat; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; import java.util.Date; import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; + /** - * Serialises a long millis-since-epoch to simple ISO date format with no time. - * @author rspace - * + * Serialises a {@link Date} to ISO date format {@code yyyy-MM-dd} with no time component. + *

+ * Dates are always serialised in UTC. A {@code Date} value is converted to its UTC calendar + * date before formatting, so callers must ensure the logical date they intend to send matches + * the UTC date of the {@code Date} instance (e.g. set to midnight UTC). + *

*/ public class ISO8601DateSerialiser extends StdSerializer { - - static final String ISO8601_FORMAT_DATE = "yyyy-MM-dd"; - /** - * - */ - private static final long serialVersionUID = 1L; - - - public ISO8601DateSerialiser() { - this(null); - } - - public ISO8601DateSerialiser(Class t) { - super(t); - } - - @Override - public void serialize(Date value, JsonGenerator gen, SerializerProvider arg2) - throws IOException, JsonProcessingException { - SimpleDateFormat iso8601 = new SimpleDateFormat(ISO8601_FORMAT_DATE); - - gen.writeString(iso8601.format(value)); - } + + private static final long serialVersionUID = 1L; + private static final DateTimeFormatter FORMATTER = + DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneOffset.UTC); + + public ISO8601DateSerialiser() { + this(null); + } + + public ISO8601DateSerialiser(Class t) { + super(t); + } + + @Override + public void serialize(Date value, JsonGenerator gen, SerializerProvider provider) + throws IOException { + gen.writeString(FORMATTER.format(value.toInstant())); + } } diff --git a/src/test/java/com/researchspace/api/clientmodel/ActivitySearchResultTest.java b/src/test/java/com/researchspace/api/clientmodel/ActivitySearchResultTest.java index 71d7e12..ca83554 100644 --- a/src/test/java/com/researchspace/api/clientmodel/ActivitySearchResultTest.java +++ b/src/test/java/com/researchspace/api/clientmodel/ActivitySearchResultTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.File; import java.io.IOException; @@ -12,7 +13,9 @@ import org.junit.jupiter.api.Test; import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; public class ActivitySearchResultTest extends AbstractModelTest { @@ -26,11 +29,22 @@ public void setUp() throws Exception { public void tearDown() throws Exception { } + @Test + void testOidFieldSerialisesCorrectly() throws JsonProcessingException { + ActivitySearchQuery q = ActivitySearchQuery.builder() + .oid("SD12345") + .domain(ActivityDomain.RECORD) + .build(); + String json = new ObjectMapper().writeValueAsString(q); + assertTrue(json.contains("\"oid\":\"SD12345\"")); + } + @Test public void test() throws JsonParseException, JsonMappingException, IOException { ActivitySearchResult searchRes = readFileToClass(ActivitySearchResultJson, ActivitySearchResult.class); assertEquals(0,searchRes.getPageNumber().intValue()); assertEquals(1,searchRes.getTotalHits().intValue()); + assertEquals(10,searchRes.getPageSize().intValue()); assertNotNull(searchRes.getActivities().get(0).getTimestamp()); Map payload = searchRes.getActivities().get(0).getPayload(); assertNotNull(payload.get("data")); diff --git a/src/test/java/com/researchspace/api/clientmodel/DocumentSearchQueryTest.java b/src/test/java/com/researchspace/api/clientmodel/DocumentSearchQueryTest.java index de28151..ad174ea 100644 --- a/src/test/java/com/researchspace/api/clientmodel/DocumentSearchQueryTest.java +++ b/src/test/java/com/researchspace/api/clientmodel/DocumentSearchQueryTest.java @@ -27,9 +27,8 @@ public void tearDown() throws Exception { @Test public void test() throws JsonParseException, JsonMappingException, IOException { - System.err.println(SearchOperator.AND.toString()); DocumentSearchQuery query = readFileToClass(DocumentSearchQueryJson, DocumentSearchQuery.class); - assertEquals(2,query.getTerms().size()); + assertEquals(2, query.getTerms().size()); assertEquals(SearchOperator.OR, query.getOperator()); diff --git a/src/test/java/com/researchspace/api/clientmodel/DocumentSearchResultTest.java b/src/test/java/com/researchspace/api/clientmodel/DocumentSearchResultTest.java index 54357b3..c059d1c 100644 --- a/src/test/java/com/researchspace/api/clientmodel/DocumentSearchResultTest.java +++ b/src/test/java/com/researchspace/api/clientmodel/DocumentSearchResultTest.java @@ -3,6 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import java.io.File; import java.io.IOException; @@ -29,9 +30,10 @@ public void tearDown() throws Exception { @Test public void test() throws JsonParseException, JsonMappingException, IOException { DocumentSearchResult searchTerm = readFileToClass(DocumentSearchResultJson, DocumentSearchResult.class); - assertEquals(0,searchTerm.getPageNumber().intValue()); - assertEquals(8,searchTerm.getTotalHits().intValue()); - System.err.println(searchTerm); + assertEquals(0, searchTerm.getPageNumber().intValue()); + assertEquals(8, searchTerm.getTotalHits().intValue()); + assertEquals(10, searchTerm.getPageSize().intValue()); + assertNotNull(searchTerm.getDocuments()); } } diff --git a/src/test/java/com/researchspace/api/clientmodel/DocumentSharesTest.java b/src/test/java/com/researchspace/api/clientmodel/DocumentSharesTest.java new file mode 100644 index 0000000..74b71da --- /dev/null +++ b/src/test/java/com/researchspace/api/clientmodel/DocumentSharesTest.java @@ -0,0 +1,37 @@ +package com.researchspace.api.clientmodel; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import java.io.InputStream; + +import static org.junit.jupiter.api.Assertions.*; + +class DocumentSharesTest { + + @Test + void deserialiseFromFixture() throws Exception { + try (InputStream is = getClass().getResourceAsStream("/DocumentShares.json")) { + assertNotNull(is, "DocumentShares.json fixture not found"); + DocumentShares result = new ObjectMapper().readValue(is, DocumentShares.class); + assertEquals(100L, result.getSharedDocId()); + assertEquals("My Document", result.getSharedDocName()); + assertEquals(1, result.getDirectShares().size()); + assertTrue(result.getNotebookShares().isEmpty()); + DocumentShareEntry entry = result.getDirectShares().get(0); + assertEquals(1L, entry.getShareId()); + assertEquals("Smith Group", entry.getRecipientName()); + assertEquals("GROUP", entry.getRecipientType()); + assertEquals("READ", entry.getPermission()); + } + } + + @Test + void ignoresUnknownFields() throws Exception { + String json = "{\"sharedDocId\":1,\"directShares\":[],\"notebookShares\":[],\"unknownFutureField\":\"x\"}"; + DocumentShares result = new ObjectMapper().readValue(json, DocumentShares.class); + assertEquals(1L, result.getSharedDocId()); + assertTrue(result.getDirectShares().isEmpty()); + } + +} diff --git a/src/test/java/com/researchspace/api/clientmodel/DocumentTest.java b/src/test/java/com/researchspace/api/clientmodel/DocumentTest.java index faa8b1f..4d81ad2 100644 --- a/src/test/java/com/researchspace/api/clientmodel/DocumentTest.java +++ b/src/test/java/com/researchspace/api/clientmodel/DocumentTest.java @@ -3,6 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import java.io.File; import java.io.IOException; @@ -29,8 +30,20 @@ public void tearDown() throws Exception { @Test public void test() throws JsonParseException, JsonMappingException, IOException { Document d = readFileToClass(documentJson, Document.class); - assertEquals(2,d.getFields().size()); - System.err.println(d); + assertEquals(2, d.getFields().size()); + assertEquals(23L, d.getId()); + assertEquals("SD23", d.getGlobalId()); + assertEquals("MyExperiment", d.getName()); + assertNotNull(d.getCreated()); + assertNotNull(d.getLastModified()); + assertNotNull(d.getOwner()); + assertEquals(1L, d.getOwner().getId()); + assertEquals("bsmith", d.getOwner().getUsername()); + assertNotNull(d.getForm()); + assertEquals(123L, d.getForm().getId()); + assertEquals(12L, d.getParentFolderId()); + assertNotNull(d.getFields().get(0).getType()); + assertNotNull(d.getFields().get(0).getName()); } } diff --git a/src/test/java/com/researchspace/api/clientmodel/FileSearchResultTest.java b/src/test/java/com/researchspace/api/clientmodel/FileSearchResultTest.java index 92b4903..efb443c 100644 --- a/src/test/java/com/researchspace/api/clientmodel/FileSearchResultTest.java +++ b/src/test/java/com/researchspace/api/clientmodel/FileSearchResultTest.java @@ -3,6 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import java.io.File; import java.io.IOException; @@ -29,9 +30,10 @@ public void tearDown() throws Exception { @Test public void test() throws JsonParseException, JsonMappingException, IOException { FileSearchResult d = readFileToClass(FileSearchResultJson, FileSearchResult.class); - assertEquals(0,d.getPageNumber().intValue()); - assertEquals(8,d.getTotalHits().intValue()); - System.err.println(d); + assertEquals(0, d.getPageNumber().intValue()); + assertEquals(8, d.getTotalHits().intValue()); + assertEquals(10, d.getPageSize().intValue()); + assertNotNull(d.getFiles()); } } diff --git a/src/test/java/com/researchspace/api/clientmodel/FolderTreeItemListingTest.java b/src/test/java/com/researchspace/api/clientmodel/FolderTreeItemListingTest.java new file mode 100644 index 0000000..95376c9 --- /dev/null +++ b/src/test/java/com/researchspace/api/clientmodel/FolderTreeItemListingTest.java @@ -0,0 +1,41 @@ +package com.researchspace.api.clientmodel; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.io.File; +import java.io.IOException; + +import org.junit.jupiter.api.Test; + +public class FolderTreeItemListingTest extends AbstractModelTest { + + File listingJson = new File("src/test/resources/FolderTreeItemListing.json"); + + @Test + void testFolderTreeListingDeserialises() throws IOException { + FolderTreeItemListing listing = readFileToClass(listingJson, FolderTreeItemListing.class); + assertNotNull(listing); + assertEquals(2L, listing.getTotalHits()); + assertEquals(0, listing.getPageNumber()); + assertEquals(10, listing.getPageSize().intValue()); + assertEquals(1L, listing.getParentId()); + assertFalse(listing.getRecords().isEmpty()); + } + + @Test + void testFolderItemFields() throws IOException { + FolderTreeItemListing listing = readFileToClass(listingJson, FolderTreeItemListing.class); + FolderTreeItemInfo first = listing.getRecords().get(0); + assertEquals(10L, first.getId()); + assertEquals("FL10", first.getGlobalId()); + assertEquals("Subfolder A", first.getName()); + assertEquals("FOLDER", first.getType()); + assertNotNull(first.getCreated()); + assertNotNull(first.getLastModified()); + assertEquals(1L, first.getParentFolderId()); + assertNotNull(first.getOwner()); + assertEquals("bsmith", first.getOwner().getUsername()); + } +} diff --git a/src/test/java/com/researchspace/api/clientmodel/FormPostTest.java b/src/test/java/com/researchspace/api/clientmodel/FormPostTest.java index 971f7d7..d222690 100644 --- a/src/test/java/com/researchspace/api/clientmodel/FormPostTest.java +++ b/src/test/java/com/researchspace/api/clientmodel/FormPostTest.java @@ -8,6 +8,9 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.researchspace.api.clientmodel.FormPost.ChoiceFieldPost; @@ -44,6 +47,15 @@ public void test() throws JsonProcessingException { .field(RadioFieldPost.builder().name("radios").options(radios).defaultOption(defaultRadio).build()) .build(); ObjectMapper reader = new ObjectMapper(); - System.err.println(reader.writeValueAsString(toSubmit)); + String json = reader.writeValueAsString(toSubmit); + assertNotNull(json); + assertTrue(json.contains("\"name\":\"formName\"")); + assertTrue(json.contains("\"type\":\"Number\"")); + assertTrue(json.contains("\"type\":\"Date\"")); + assertTrue(json.contains("\"type\":\"String\"")); + assertTrue(json.contains("\"type\":\"Text\"")); + assertTrue(json.contains("\"type\":\"Choice\"")); + assertTrue(json.contains("\"type\":\"Time\"")); + assertTrue(json.contains("\"type\":\"Radio\"")); } } diff --git a/src/test/java/com/researchspace/api/clientmodel/FormSearchResultTest.java b/src/test/java/com/researchspace/api/clientmodel/FormSearchResultTest.java index b2ccd0f..6d41bfa 100644 --- a/src/test/java/com/researchspace/api/clientmodel/FormSearchResultTest.java +++ b/src/test/java/com/researchspace/api/clientmodel/FormSearchResultTest.java @@ -16,7 +16,7 @@ void test() throws IOException { FormSearchResult formSearchResult = readFileToClass(formSearchResultJson, FormSearchResult.class); assertEquals(0, formSearchResult.getPageNumber().intValue()); assertEquals(5, formSearchResult.getTotalHits().intValue()); - System.err.println(formSearchResult); + assertEquals(10, formSearchResult.getPageSize().intValue()); } } \ No newline at end of file diff --git a/src/test/java/com/researchspace/api/clientmodel/GroupInfoTest.java b/src/test/java/com/researchspace/api/clientmodel/GroupInfoTest.java new file mode 100644 index 0000000..8db3b28 --- /dev/null +++ b/src/test/java/com/researchspace/api/clientmodel/GroupInfoTest.java @@ -0,0 +1,55 @@ +package com.researchspace.api.clientmodel; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.io.IOException; + +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class GroupInfoTest { + + private ObjectMapper om = new ObjectMapper() + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + + @Test + void testGroupInfoDeserialisation() throws IOException { + String json = "{" + + "\"id\":10," + + "\"globalId\":\"GP10\"," + + "\"name\":\"My Lab Group\"," + + "\"type\":\"LAB_GROUP\"," + + "\"sharedFolderId\":99," + + "\"members\":[" + + " {\"id\":1,\"username\":\"pi_user\",\"role\":\"PI\"}" + + "]," + + "\"_links\":[]" + + "}"; + GroupInfo group = om.readValue(json, GroupInfo.class); + assertEquals(10L, group.getId()); + assertEquals("GP10", group.getGlobalId()); + assertEquals("My Lab Group", group.getName()); + assertEquals("LAB_GROUP", group.getType()); + assertEquals(99L, group.getSharedFolderId()); + assertEquals(1, group.getMembers().size()); + assertEquals("PI", group.getMembers().get(0).getRole()); + assertEquals(1L, group.getMembers().get(0).getId()); + assertEquals("pi_user", group.getMembers().get(0).getUsername()); + } + + @Test + void testGroupInfoIgnoresUnknownFields() throws IOException { + String json = "{" + + "\"id\":5," + + "\"name\":\"Group\"," + + "\"futureField\":\"value\"," + + "\"members\":[]" + + "}"; + GroupInfo group = om.readValue(json, GroupInfo.class); + assertNotNull(group); + assertEquals(5L, group.getId()); + } +} diff --git a/src/test/java/com/researchspace/api/clientmodel/GroupPostTest.java b/src/test/java/com/researchspace/api/clientmodel/GroupPostTest.java index 64d9d2d..b5881ee 100644 --- a/src/test/java/com/researchspace/api/clientmodel/GroupPostTest.java +++ b/src/test/java/com/researchspace/api/clientmodel/GroupPostTest.java @@ -1,6 +1,8 @@ package com.researchspace.api.clientmodel; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.junit.jupiter.api.Test; import com.researchspace.api.clientmodel.UserGroupPost.RoleInGroup; @@ -13,11 +15,17 @@ public void groupPostUsage() { .email("email").password("password") .firstName("first").lastName("last") .role(UserRole.ROLE_PI).build(); - // create user, then can create group. - + assertEquals("pi", userPost.getUsername()); + assertEquals(UserRole.ROLE_PI, userPost.getRole()); + GroupPost grpPost = GroupPost.builder().displayName("groupName").type(GroupType.LAB_GROUP) .user(UserGroupPost.builder().username("pi").roleInGroup(RoleInGroup.PI).build()) .user(UserGroupPost.builder().username("pi").roleInGroup(RoleInGroup.RS_LAB_ADMIN).build()) .build(); + assertEquals("groupName", grpPost.getDisplayName()); + assertEquals(GroupType.LAB_GROUP, grpPost.getType()); + assertEquals(2, grpPost.getUsers().size()); + assertEquals(RoleInGroup.PI, grpPost.getUsers().get(0).getRoleInGroup()); + assertEquals(RoleInGroup.RS_LAB_ADMIN, grpPost.getUsers().get(1).getRoleInGroup()); } } diff --git a/src/test/java/com/researchspace/api/clientmodel/GroupSearchResultTest.java b/src/test/java/com/researchspace/api/clientmodel/GroupSearchResultTest.java new file mode 100644 index 0000000..0d1a262 --- /dev/null +++ b/src/test/java/com/researchspace/api/clientmodel/GroupSearchResultTest.java @@ -0,0 +1,29 @@ +package com.researchspace.api.clientmodel; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.io.File; +import java.io.IOException; + +import org.junit.jupiter.api.Test; + +public class GroupSearchResultTest extends AbstractModelTest { + + private final File fixture = new File("src/test/resources/GroupSearchResult.json"); + + @Test + void testGroupSearchResultDeserialisesFromFixture() throws IOException { + GroupSearchResult result = readFileToClass(fixture, GroupSearchResult.class); + assertEquals(1L, result.getTotalHits().longValue()); + assertEquals(0, result.getPageNumber().intValue()); + assertEquals(20, result.getPageSize().intValue()); + assertNotNull(result.getGroups()); + assertEquals(1, result.getGroups().size()); + GroupInfo group = result.getGroups().get(0); + assertEquals(10L, group.getId()); + assertEquals("GP10", group.getGlobalId()); + assertEquals("My Lab Group", group.getName()); + assertEquals("LAB_GROUP", group.getType()); + } +} diff --git a/src/test/java/com/researchspace/api/clientmodel/MoveRequestTest.java b/src/test/java/com/researchspace/api/clientmodel/MoveRequestTest.java new file mode 100644 index 0000000..dd7d030 --- /dev/null +++ b/src/test/java/com/researchspace/api/clientmodel/MoveRequestTest.java @@ -0,0 +1,57 @@ +package com.researchspace.api.clientmodel; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; + +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class MoveRequestTest { + + @Test + void testMoveRequestBuilder() { + MoveRequest req = MoveRequest.builder() + .recordId(42L) + .sourceFolderId(10L) + .targetFolderId(20L) + .currentGrandparentId(5L) + .reason("moving to new location") + .build(); + + assertEquals(42L, req.getRecordId()); + assertEquals(10L, req.getSourceFolderId()); + assertEquals(20L, req.getTargetFolderId()); + assertEquals(5L, req.getCurrentGrandparentId()); + assertEquals("moving to new location", req.getReason()); + } + + @Test + void testMoveRequestSerialisesCorrectly() throws JsonProcessingException { + MoveRequest req = MoveRequest.builder() + .recordId(1L) + .targetFolderId(2L) + .build(); + String json = new ObjectMapper().writeValueAsString(req); + // server API field is "docId"; @JsonProperty maps recordId → docId + assertTrue(json.contains("\"docId\":1"), "Expected docId in JSON but got: " + json); + assertTrue(json.contains("\"targetFolderId\":2"), "Expected targetFolderId in JSON but got: " + json); + } + + @Test + void testMoveRequestRoundtrip() throws IOException { + MoveRequest original = MoveRequest.builder() + .recordId(99L) + .sourceFolderId(5L) + .targetFolderId(7L) + .reason("test move") + .build(); + ObjectMapper om = new ObjectMapper(); + String json = om.writeValueAsString(original); + MoveRequest deserialised = om.readValue(json, MoveRequest.class); + assertEquals(original, deserialised); + } +} diff --git a/src/test/java/com/researchspace/api/clientmodel/SharePermissionUpdateTest.java b/src/test/java/com/researchspace/api/clientmodel/SharePermissionUpdateTest.java new file mode 100644 index 0000000..ffb960e --- /dev/null +++ b/src/test/java/com/researchspace/api/clientmodel/SharePermissionUpdateTest.java @@ -0,0 +1,29 @@ +package com.researchspace.api.clientmodel; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class SharePermissionUpdateTest { + + @Test + void roundTrip() throws Exception { + SharePermissionUpdate req = SharePermissionUpdate.builder() + .shareId(42L).permission("WRITE").build(); + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writeValueAsString(req); + SharePermissionUpdate result = mapper.readValue(json, SharePermissionUpdate.class); + assertEquals(req, result); + } + + @Test + void noArgConstructorAndSetters() { + SharePermissionUpdate req = new SharePermissionUpdate(); + req.setShareId(7L); + req.setPermission("READ"); + assertEquals(7L, req.getShareId()); + assertEquals("READ", req.getPermission()); + } + +} diff --git a/src/test/java/com/researchspace/api/clientmodel/UserInfoTest.java b/src/test/java/com/researchspace/api/clientmodel/UserInfoTest.java new file mode 100644 index 0000000..398c499 --- /dev/null +++ b/src/test/java/com/researchspace/api/clientmodel/UserInfoTest.java @@ -0,0 +1,52 @@ +package com.researchspace.api.clientmodel; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.File; +import java.io.IOException; + +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class UserInfoTest extends AbstractModelTest { + + private final File fixture = new File("src/test/resources/UserInfo.json"); + + @Test + void testUserInfoDeserialisesFromFixture() throws IOException { + UserInfo user = readFileToClass(fixture, UserInfo.class); + assertEquals(101L, user.getId()); + assertEquals("U101", user.getGlobalId()); + assertEquals("jsmith", user.getUsername()); + assertEquals("jsmith@lab.org", user.getEmail()); + assertEquals("John", user.getFirstName()); + assertEquals("Smith", user.getLastName()); + assertEquals(UserRole.ROLE_USER, user.getRole()); + assertEquals("Acme Labs", user.getAffiliation()); + assertTrue(user.isEnabled()); + assertEquals(200L, user.getHomeFolderId()); + } + + @Test + void testUserInfoIgnoresUnknownFields() throws IOException { + String json = "{\"id\":1,\"globalId\":\"U1\",\"name\":\"testuser\",\"username\":\"testuser\",\"unknownFutureField\":\"some value\"}"; + UserInfo user = new ObjectMapper().readValue(json, UserInfo.class); + assertNotNull(user); + assertEquals(1L, user.getId()); + assertEquals("testuser", user.getUsername()); + } + + @Test + void testUserInfoRoleIsNullWhenNotPresent() throws IOException { + String json = "{\"id\":2,\"username\":\"noRole\"}"; + UserInfo user = new ObjectMapper() + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .readValue(json, UserInfo.class); + assertNull(user.getRole()); + } +} diff --git a/src/test/java/com/researchspace/api/clientmodel/UserSearchResultTest.java b/src/test/java/com/researchspace/api/clientmodel/UserSearchResultTest.java new file mode 100644 index 0000000..0bcd44b --- /dev/null +++ b/src/test/java/com/researchspace/api/clientmodel/UserSearchResultTest.java @@ -0,0 +1,35 @@ +package com.researchspace.api.clientmodel; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.io.File; +import java.io.IOException; + +import org.junit.jupiter.api.Test; + +public class UserSearchResultTest extends AbstractModelTest { + + private final File fixture = new File("src/test/resources/UserSearchResult.json"); + + @Test + void testUserSearchResultDeserialisesFromFixture() throws IOException { + UserSearchResult result = readFileToClass(fixture, UserSearchResult.class); + assertEquals(1L, result.getTotalHits().longValue()); + assertEquals(0, result.getPageNumber().intValue()); + assertEquals(20, result.getPageSize().intValue()); + assertNotNull(result.getUsers()); + assertEquals(1, result.getUsers().size()); + + UserInfo user = result.getUsers().get(0); + assertEquals(1L, user.getId()); + assertEquals("U1", user.getGlobalId()); + assertEquals("jdoe", user.getUsername()); + assertEquals("jdoe@lab.org", user.getEmail()); + assertEquals("Jane", user.getFirstName()); + assertEquals("Doe", user.getLastName()); + assertEquals(UserRole.ROLE_PI, user.getRole()); + assertEquals("Research Lab", user.getAffiliation()); + assertEquals(10L, user.getHomeFolderId()); + } +} diff --git a/src/test/java/com/researchspace/api/clientmodel/UserTest.java b/src/test/java/com/researchspace/api/clientmodel/UserTest.java new file mode 100644 index 0000000..df5f4ea --- /dev/null +++ b/src/test/java/com/researchspace/api/clientmodel/UserTest.java @@ -0,0 +1,57 @@ +package com.researchspace.api.clientmodel; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.io.File; +import java.io.IOException; + +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class UserTest extends AbstractModelTest { + + File userJson = new File("src/test/resources/User.json"); + + @Test + void testUserDeserialisationFromFixture() throws IOException { + User user = readFileToClass(userJson, User.class); + assertEquals(42L, user.getId()); + assertEquals("testuser", user.getUsername()); + assertEquals("test@example.com", user.getEmail()); + assertEquals("Test", user.getFirstName()); + assertEquals("User", user.getLastName()); + assertEquals(100L, user.getHomeFolderId()); + } + + @Test + void testUserIgnoresUnknownFields() throws IOException { + String json = "{\"id\":1,\"username\":\"user\",\"unknownFutureField\":\"some value\"}"; + User user = new ObjectMapper() + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .readValue(json, User.class); + assertNotNull(user); + assertEquals(1L, user.getId()); + } + + @Test + void testAllFieldsDeserialise() throws IOException { + String json = "{" + + "\"id\":7," + + "\"username\":\"jdoe\"," + + "\"email\":\"jdoe@lab.org\"," + + "\"firstName\":\"Jane\"," + + "\"lastName\":\"Doe\"," + + "\"homeFolderId\":55" + + "}"; + User user = new ObjectMapper().readValue(json, User.class); + assertEquals(7L, user.getId()); + assertEquals("jdoe", user.getUsername()); + assertEquals("jdoe@lab.org", user.getEmail()); + assertEquals("Jane", user.getFirstName()); + assertEquals("Doe", user.getLastName()); + assertEquals(55L, user.getHomeFolderId()); + } +} diff --git a/src/test/resources/ActivitySearchResult.json b/src/test/resources/ActivitySearchResult.json index 501e7f0..4baae12 100644 --- a/src/test/resources/ActivitySearchResult.json +++ b/src/test/resources/ActivitySearchResult.json @@ -1,6 +1,7 @@ { "totalHits": 1, "pageNumber": 0, + "pageSize": 10, "activities": [ { "username": "bob1234", diff --git a/src/test/resources/DocumentSearchResult.json b/src/test/resources/DocumentSearchResult.json index ade6081..afecfcc 100644 --- a/src/test/resources/DocumentSearchResult.json +++ b/src/test/resources/DocumentSearchResult.json @@ -1,6 +1,7 @@ { "totalHits" : 8, "pageNumber" : 0, + "pageSize" : 10, "documents" : [ { "id" : 476, "globalId" : "SD476", diff --git a/src/test/resources/DocumentShares.json b/src/test/resources/DocumentShares.json new file mode 100644 index 0000000..ae5102f --- /dev/null +++ b/src/test/resources/DocumentShares.json @@ -0,0 +1,19 @@ +{ + "sharedDocId": 100, + "sharedDocName": "My Document", + "directShares": [ + { + "shareId": 1, + "sharerId": 10, + "sharerName": "jsmith", + "recipientId": 20, + "recipientName": "Smith Group", + "recipientType": "GROUP", + "permission": "READ", + "parentId": 30, + "path": "/Shared/Smith Group", + "grandparentId": null + } + ], + "notebookShares": [] +} diff --git a/src/test/resources/FileSearchResult.json b/src/test/resources/FileSearchResult.json index f88c83e..819609c 100644 --- a/src/test/resources/FileSearchResult.json +++ b/src/test/resources/FileSearchResult.json @@ -1,6 +1,7 @@ { "totalHits" : 8, "pageNumber" : 0, + "pageSize" : 10, "files":[ { "id": 1246, diff --git a/src/test/resources/FolderTreeItemListing.json b/src/test/resources/FolderTreeItemListing.json new file mode 100644 index 0000000..3f6a70a --- /dev/null +++ b/src/test/resources/FolderTreeItemListing.json @@ -0,0 +1,43 @@ +{ + "totalHits": 2, + "pageNumber": 0, + "pageSize": 10, + "parentId": 1, + "records": [ + { + "id": 10, + "globalId": "FL10", + "name": "Subfolder A", + "type": "FOLDER", + "created": "2023-01-01T00:00:00.000Z", + "lastModified": "2023-06-01T00:00:00.000Z", + "parentFolderId": 1, + "owner": { + "id": 1, + "username": "bsmith", + "email": "bsmith@example.com", + "firstName": "Bob", + "lastName": "Smith" + }, + "_links": [] + }, + { + "id": 11, + "globalId": "NB11", + "name": "My Notebook", + "type": "NOTEBOOK", + "created": "2023-02-01T00:00:00.000Z", + "lastModified": "2023-07-01T00:00:00.000Z", + "parentFolderId": 1, + "owner": { + "id": 1, + "username": "bsmith", + "email": "bsmith@example.com", + "firstName": "Bob", + "lastName": "Smith" + }, + "_links": [] + } + ], + "_links": [] +} diff --git a/src/test/resources/FormSearchResult.json b/src/test/resources/FormSearchResult.json index c1e6f54..af514b5 100644 --- a/src/test/resources/FormSearchResult.json +++ b/src/test/resources/FormSearchResult.json @@ -1,6 +1,7 @@ { "totalHits": 5, "pageNumber": 0, + "pageSize": 10, "forms": [ { "id": 32785, diff --git a/src/test/resources/GroupSearchResult.json b/src/test/resources/GroupSearchResult.json new file mode 100644 index 0000000..9024609 --- /dev/null +++ b/src/test/resources/GroupSearchResult.json @@ -0,0 +1,16 @@ +{ + "totalHits": 1, + "pageNumber": 0, + "pageSize": 20, + "groups": [ + { + "id": 10, + "globalId": "GP10", + "name": "My Lab Group", + "type": "LAB_GROUP", + "sharedFolderId": 99, + "members": [] + } + ], + "_links": [] +} diff --git a/src/test/resources/User.json b/src/test/resources/User.json new file mode 100644 index 0000000..b3b93d1 --- /dev/null +++ b/src/test/resources/User.json @@ -0,0 +1,8 @@ +{ + "id": 42, + "username": "testuser", + "email": "test@example.com", + "firstName": "Test", + "lastName": "User", + "homeFolderId": 100 +} diff --git a/src/test/resources/UserInfo.json b/src/test/resources/UserInfo.json new file mode 100644 index 0000000..622f704 --- /dev/null +++ b/src/test/resources/UserInfo.json @@ -0,0 +1,14 @@ +{ + "id": 101, + "globalId": "U101", + "name": "jsmith", + "username": "jsmith", + "email": "jsmith@lab.org", + "firstName": "John", + "lastName": "Smith", + "role": "ROLE_USER", + "affiliation": "Acme Labs", + "enabled": true, + "homeFolderId": 200, + "_links": [] +} diff --git a/src/test/resources/UserSearchResult.json b/src/test/resources/UserSearchResult.json new file mode 100644 index 0000000..e2c0c36 --- /dev/null +++ b/src/test/resources/UserSearchResult.json @@ -0,0 +1,21 @@ +{ + "totalHits": 1, + "pageNumber": 0, + "pageSize": 20, + "users": [ + { + "id": 1, + "globalId": "U1", + "name": "jdoe", + "username": "jdoe", + "email": "jdoe@lab.org", + "firstName": "Jane", + "lastName": "Doe", + "role": "ROLE_PI", + "affiliation": "Research Lab", + "enabled": true, + "homeFolderId": 10 + } + ], + "_links": [] +}