feat(import): source values for exports and bookmarklet
Build, Test & Push Core Service / quality-check (push) Successful in 1m9s
Build, Test & Push Core Service / docker (push) Successful in 1m33s

This commit is contained in:
lobo committed 2026-09-30 15:59:05 +02:00
1 parent e347b7aac8
commit 216c1af62f
3 files changed
+16 -2

No files matched your search

+1 -1
View File
@@ -121,7 +121,7 @@ ArchUnit role rules (`RoleAnnotationRules`) and `src/test/resources/contract/aut
| `PUT` | `/api/library/games/{appid}/status` (status only, keeps rating, notes, priority) | JWT | | `PUT` | `/api/library/games/{appid}/status` (status only, keeps rating, notes, priority) | JWT |
| `PUT` | `/api/library/games/{appid}/finished-hint` (`{dismissed: ENDING\|PLAYTIME}`, "Not yet"; `204`) | JWT | | `PUT` | `/api/library/games/{appid}/finished-hint` (`{dismissed: ENDING\|PLAYTIME}`, "Not yet"; `204`) | JWT |
| `PUT` | `/api/library/games/{appid}/hidden` (`{hidden}`; `409 MANUAL_GAME` for a game added by hand) | JWT | | `PUT` | `/api/library/games/{appid}/hidden` (`{hidden}`; `409 MANUAL_GAME` for a game added by hand) | JWT |
| `POST` | `/api/library/imports` (`{source: TEXT\|CSV\|SEARCH, rows: [{title, platform, playtimeMinutes, status, igdbId}]}`, 1–1000 rows; `202 {id}` in `QUEUED`, `409 IMPORT_RUNNING`, `503 IGDB_OFF`) | JWT | | `POST` | `/api/library/imports` (`{source: TEXT\|CSV\|SEARCH\|GALAXY\|GROUVEE\|HLTB\|PLAYNITE\|BOOKMARKLET, rows: [{title, platform, playtimeMinutes, status, igdbId}]}`, 1–1000 rows; `202 {id}` in `QUEUED`, `409 IMPORT_RUNNING`, `503 IGDB_OFF`) | JWT |
| `GET` | `/api/library/imports` (`{imports}`, the last 20), `/api/library/imports/{id}` (status, progress counts, `ahead` while it waits in a queue, `attempts`; the rows with their candidates while `READY`) | JWT | | `GET` | `/api/library/imports` (`{imports}`, the last 20), `/api/library/imports/{id}` (status, progress counts, `ahead` while it waits in a queue, `attempts`; the rows with their candidates while `READY`) | JWT |
| `POST` | `/api/library/imports/{id}/save` (`{rows: [{lineNo, igdbId, platform, status, playtimeMinutes}]}`; `202`, then poll until `SAVED`; `409 IMPORT_NOT_READY`) | JWT | | `POST` | `/api/library/imports/{id}/save` (`{rows: [{lineNo, igdbId, platform, status, playtimeMinutes}]}`; `202`, then poll until `SAVED`; `409 IMPORT_NOT_READY`) | JWT |
| `POST` | `/api/library/imports/{id}/retry` (a `FAILED` import; `202`, `409 IMPORT_NOT_FAILED` / `IMPORT_RUNNING`) | JWT | | `POST` | `/api/library/imports/{id}/retry` (a `FAILED` import; `202`, `409 IMPORT_NOT_FAILED` / `IMPORT_RUNNING`) | JWT |
@@ -18,7 +18,11 @@ public record GameImport(long id, long userId, Source source, Status status, int
int saved, int added, boolean running, int attempts, Step step, Instant createdAt, int saved, int added, boolean running, int attempts, Step step, Instant createdAt,
Instant queuedAt, Instant savedAt) { Instant queuedAt, Instant savedAt) {
public enum Source { TEXT, CSV, SEARCH } /**
* Where the lines came from. GALAXY, GROUVEE, HLTB and PLAYNITE are exports the Frontend reads; BOOKMARKLET is
* the list read on a store page. Core treats them all alike.
*/
public enum Source { TEXT, CSV, SEARCH, GALAXY, GROUVEE, HLTB, PLAYNITE, BOOKMARKLET }
public enum Status { QUEUED, MATCHING, READY, SAVING, SAVED, UNDONE, FAILED } public enum Status { QUEUED, MATCHING, READY, SAVING, SAVED, UNDONE, FAILED }
@@ -12,6 +12,8 @@ import core_service.shared.test.AbstractMockedAdaptersTest;
import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.JsonPath;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.provider.ValueSource;
import org.junit.jupiter.params.ParameterizedTest;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@@ -195,6 +197,14 @@ class GameImportControllerTest extends AbstractMockedAdaptersTest {
verify(igdbApiService, never()).searchGames(any()); verify(igdbApiService, never()).searchGames(any());
} }
@ParameterizedTest
@ValueSource(strings = {"GALAXY", "GROUVEE", "HLTB", "PLAYNITE", "BOOKMARKLET"})
void create_ExportAndBookmarkletSources_AreStored(String source) throws Exception {
long id = createReady("{\"source\": \"" + source + "\", \"rows\": [{\"title\": \"Elden Ring\"}]}");
assertEquals(source, jdbc.queryForObject("select source from game_import where id = ?", String.class, id));
}
@Test @Test
void create_TooManyRowsOrNoTitle_Is400() throws Exception { void create_TooManyRowsOrNoTitle_Is400() throws Exception {
String row = "{\"title\": \"Game\"}"; String row = "{\"title\": \"Game\"}";