diff --git a/game-app/game-core/src/main/java/games/strategy/engine/framework/map/download/DownloadFileParser.java b/game-app/game-core/src/main/java/games/strategy/engine/framework/map/download/DownloadFileParser.java deleted file mode 100644 index e2cacbec091..00000000000 --- a/game-app/game-core/src/main/java/games/strategy/engine/framework/map/download/DownloadFileParser.java +++ /dev/null @@ -1,71 +0,0 @@ -package games.strategy.engine.framework.map.download; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.Strings; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import lombok.experimental.UtilityClass; -import org.triplea.http.client.maps.listing.MapDownloadListing; -import org.triplea.yaml.YamlReader; -import org.triplea.yaml.YamlReader.InvalidYamlFormatException; - -/** - * Utility class to parse an available map list file config file - used to determine which maps are - * available for download. - */ -@UtilityClass -final class DownloadFileParser { - - enum Tags { - url, - version, - mapName, - description, - mapCategory, - img - } - - public static List parse(final InputStream is) throws IOException { - try { - return parseImpl(is); - } catch (final InvalidYamlFormatException e) { - throw new IOException(e); - } - } - - private static List parseImpl(final InputStream is) { - final List> yamlData = YamlReader.readList(is); - - final List downloads = new ArrayList<>(); - yamlData.stream() - .map(Map.class::cast) - .forEach( - yaml -> { - final String url = (String) checkNotNull(yaml.get(Tags.url.toString())); - final String description = - (String) checkNotNull(yaml.get(Tags.description.toString())); - final String mapName = (String) checkNotNull(yaml.get(Tags.mapName.toString())); - - final Integer version = (Integer) yaml.get(Tags.version.toString()); - - final String mapCategory = - (String) yaml.getOrDefault(Tags.mapCategory.toString(), "EXPERIMENTAL"); - - final String img = Strings.nullToEmpty((String) yaml.get(Tags.img.toString())); - downloads.add( - MapDownloadListing.builder() - .downloadUrl(url) - .description(description) - .mapName(mapName) - .version(version) - .mapCategory(mapCategory) - .previewImageUrl(img) - .build()); - }); - return downloads; - } -} diff --git a/game-app/game-core/src/main/java/games/strategy/engine/framework/map/download/DownloadRunnable.java b/game-app/game-core/src/main/java/games/strategy/engine/framework/map/download/DownloadRunnable.java deleted file mode 100644 index 6df4d477e13..00000000000 --- a/game-app/game-core/src/main/java/games/strategy/engine/framework/map/download/DownloadRunnable.java +++ /dev/null @@ -1,25 +0,0 @@ -package games.strategy.engine.framework.map.download; - -import java.util.List; -import lombok.AllArgsConstructor; -import org.triplea.http.client.maps.listing.MapDownloadListing; -import org.triplea.http.client.maps.listing.MapsListingClient; - -/** - * Downloads a map index file, parses it and returns a List of - * DownloadFileDescription. - */ -@AllArgsConstructor -public class DownloadRunnable implements MapsListingClient { - - /** URL of the maps YAML file */ - private final String url; - - /** Parses a file at the given URL. If an error occurs this will return an empty list. */ - @Override - public List fetchMapDownloads() { - return DownloadConfiguration.contentReader() - .download(url, DownloadFileParser::parse) - .orElseGet(List::of); - } -} diff --git a/game-app/game-core/src/main/java/games/strategy/engine/framework/map/download/MapDownloadSwingTable.java b/game-app/game-core/src/main/java/games/strategy/engine/framework/map/download/MapDownloadSwingTable.java index 1623c23f192..17caef36eea 100644 --- a/game-app/game-core/src/main/java/games/strategy/engine/framework/map/download/MapDownloadSwingTable.java +++ b/game-app/game-core/src/main/java/games/strategy/engine/framework/map/download/MapDownloadSwingTable.java @@ -1,5 +1,6 @@ package games.strategy.engine.framework.map.download; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; @@ -9,6 +10,7 @@ import javax.swing.JTable; import javax.swing.table.DefaultTableModel; import org.triplea.http.client.maps.listing.MapDownloadListing; +import org.triplea.http.client.maps.listing.MapTag; import org.triplea.swing.JTableBuilder; /** @@ -19,17 +21,53 @@ public class MapDownloadSwingTable { private final JTable table; public MapDownloadSwingTable(final Collection maps) { + // Build a jtable that has n+1 columns, the first column (+1) is the map name, + // the 'n' columns are one for each tag. + // Note, not all maps have all tags (potentially sparse), we will display a blank + // value if a map does not have a given tag. + + final List columnNames = new ArrayList<>(); + columnNames.add("Map"); + + // Get the full set of all tag names in display order + final List tagNames = + maps.stream() + .map(MapDownloadListing::getMapTags) + .flatMap(Collection::stream) + .sorted(Comparator.comparing(MapTag::getDisplayOrder)) + .map(MapTag::getName) + .distinct() + .collect(Collectors.toList()); + + columnNames.addAll(tagNames); // .stream().map(MapTag::getName).collect(Collectors.toList())); + table = JTableBuilder.builder() - .columnNames("Map", "Category") + .columnNames(columnNames) .rowData( maps.stream() .sorted(Comparator.comparing(MapDownloadListing::getMapName)) .collect(Collectors.toList())) - .rowMapper(map -> List.of(map.getMapName(), map.getMapCategory())) + .rowMapper(mapDownloadListing -> rowMapper(mapDownloadListing, tagNames)) .build(); } + /** + * Given a download item and a set of tags (in correct display order), returns values for a table + * row, map name and then each of the map's tag values. + */ + private List rowMapper( + final MapDownloadListing mapDownloadListing, final List mapTags) { + final List rowValues = new ArrayList<>(); + rowValues.add(mapDownloadListing.getMapName()); + + for (final String tag : mapTags) { + final String tagValue = mapDownloadListing.getTagValue(tag); + rowValues.add(tagValue); + } + return rowValues; + } + public JTable getSwingComponent() { // select first row, will trigger any selection listeners table.setRowSelectionInterval(0, 0); diff --git a/game-app/game-core/src/main/java/games/strategy/engine/framework/map/listing/MapListingFetcher.java b/game-app/game-core/src/main/java/games/strategy/engine/framework/map/listing/MapListingFetcher.java index 301a0291092..5e4233a3a18 100644 --- a/game-app/game-core/src/main/java/games/strategy/engine/framework/map/listing/MapListingFetcher.java +++ b/game-app/game-core/src/main/java/games/strategy/engine/framework/map/listing/MapListingFetcher.java @@ -1,12 +1,8 @@ package games.strategy.engine.framework.map.listing; -import games.strategy.engine.framework.map.download.DownloadRunnable; -import games.strategy.triplea.UrlConstants; -import games.strategy.triplea.settings.ClientSetting; import java.util.List; import lombok.experimental.UtilityClass; import org.triplea.http.client.maps.listing.MapDownloadListing; -import org.triplea.http.client.maps.listing.MapsListingClient; import org.triplea.http.client.maps.listing.MapsListingHttpClient; import org.triplea.live.servers.LiveServersFetcher; @@ -15,11 +11,7 @@ public class MapListingFetcher { /** Fetches the full listing of maps that are available for download. */ public static List getMapDownloadList() { - final MapsListingClient mapsListingClient = - ClientSetting.useMapsServerBetaFeature.getValue().orElse(false) - ? new MapsListingHttpClient(new LiveServersFetcher().serverForCurrentVersion().getUri()) - : new DownloadRunnable(UrlConstants.MAP_DOWNLOAD_LIST); - - return mapsListingClient.fetchMapDownloads(); + final var serverUri = new LiveServersFetcher().serverForCurrentVersion().getUri(); + return new MapsListingHttpClient(serverUri).fetchMapDownloads(); } } diff --git a/game-app/game-core/src/main/java/games/strategy/triplea/settings/ClientSetting.java b/game-app/game-core/src/main/java/games/strategy/triplea/settings/ClientSetting.java index 9a487573211..3802ac128c3 100644 --- a/game-app/game-core/src/main/java/games/strategy/triplea/settings/ClientSetting.java +++ b/game-app/game-core/src/main/java/games/strategy/triplea/settings/ClientSetting.java @@ -131,8 +131,6 @@ public abstract class ClientSetting implements GameSetting { new BooleanClientSetting("USE_WEBSOCKET_NETWORK"); public static final ClientSetting showSerializeFeatures = new BooleanClientSetting("SHOW_SERIALIZE_FEATURES"); - public static final ClientSetting useMapsServerBetaFeature = - new BooleanClientSetting("USE_MAPS_SERVER_BETA_FEATURES"); public static final BooleanClientSetting showChatTimeSettings = new BooleanClientSetting("SHOW_CHAT_TIME"); public static final BooleanClientSetting showCommentLog = diff --git a/game-app/game-core/src/main/java/games/strategy/triplea/settings/ClientSettingSwingUiBinding.java b/game-app/game-core/src/main/java/games/strategy/triplea/settings/ClientSettingSwingUiBinding.java index 9669bf6e84b..02c7c36a939 100644 --- a/game-app/game-core/src/main/java/games/strategy/triplea/settings/ClientSettingSwingUiBinding.java +++ b/game-app/game-core/src/main/java/games/strategy/triplea/settings/ClientSettingSwingUiBinding.java @@ -267,16 +267,6 @@ public SelectionComponent newSelectionComponent() { } }, - USE_MAPS_SERVER_BETA_FEATURE( - "Use Maps Server (Beta)", - SettingType.TESTING, - "Toggles whether to use the in 'beta' map server") { - @Override - public SelectionComponent newSelectionComponent() { - return booleanRadioButtons(ClientSetting.useMapsServerBetaFeature); - } - }, - LOBBY_URI_OVERRIDE_BINDING("Lobby URI Override", SettingType.TESTING, "Overrides the lobby URI") { @Override public SelectionComponent newSelectionComponent() { diff --git a/game-app/game-core/src/test/java/games/strategy/engine/ClientContextIntegrationTest.java b/game-app/game-core/src/test/java/games/strategy/engine/ClientContextIntegrationTest.java deleted file mode 100644 index 638f22eafd0..00000000000 --- a/game-app/game-core/src/test/java/games/strategy/engine/ClientContextIntegrationTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package games.strategy.engine; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.empty; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.notNullValue; - -import games.strategy.engine.framework.map.listing.MapListingFetcher; -import games.strategy.triplea.settings.AbstractClientSettingTestCase; -import java.util.List; -import org.junit.jupiter.api.Test; -import org.triplea.http.client.maps.listing.MapDownloadListing; - -class ClientContextIntegrationTest extends AbstractClientSettingTestCase { - - @Test - void downloadListOfAvailableMaps() { - final List list = MapListingFetcher.getMapDownloadList(); - - assertThat(list, notNullValue()); - assertThat(list, not(empty())); - } -} diff --git a/game-app/game-core/src/test/java/games/strategy/engine/auto/update/UpdatedMapsCheckTest.java b/game-app/game-core/src/test/java/games/strategy/engine/auto/update/UpdatedMapsCheckTest.java index 3f30461b0a1..282ea285b9c 100644 --- a/game-app/game-core/src/test/java/games/strategy/engine/auto/update/UpdatedMapsCheckTest.java +++ b/game-app/game-core/src/test/java/games/strategy/engine/auto/update/UpdatedMapsCheckTest.java @@ -92,7 +92,8 @@ private static MapDownloadListing buildDownloadDescription( .mapName(mapName) .version(version) .downloadUrl("url") - .mapCategory("category") + .previewImageUrl("preview-url") + .lastCommitDateEpochMilli(50L) .build(); } diff --git a/game-app/game-core/src/test/java/games/strategy/engine/framework/map/download/DownloadFileTest.java b/game-app/game-core/src/test/java/games/strategy/engine/framework/map/download/DownloadFileTest.java index 66b5050a21f..cd64cc46f18 100644 --- a/game-app/game-core/src/test/java/games/strategy/engine/framework/map/download/DownloadFileTest.java +++ b/game-app/game-core/src/test/java/games/strategy/engine/framework/map/download/DownloadFileTest.java @@ -16,10 +16,11 @@ void testBasicStartCancel() { final MapDownloadListing mapDownloadListing = MapDownloadListing.builder() .downloadUrl("url") + .previewImageUrl("preview-url") .description("description") .mapName("mapName") .version(0) - .mapCategory("BEST") + .lastCommitDateEpochMilli(60L) .build(); final DownloadFile testObj = new DownloadFile(mapDownloadListing, mock(DownloadListener.class)); assertThat(testObj.getDownloadState(), is(DownloadState.NOT_STARTED)); diff --git a/game-app/game-core/src/test/java/games/strategy/engine/framework/map/download/DownloadMapsWindowMapsListingTest.java b/game-app/game-core/src/test/java/games/strategy/engine/framework/map/download/DownloadMapsWindowMapsListingTest.java index e5c10620c7a..7aabf6547a1 100644 --- a/game-app/game-core/src/test/java/games/strategy/engine/framework/map/download/DownloadMapsWindowMapsListingTest.java +++ b/game-app/game-core/src/test/java/games/strategy/engine/framework/map/download/DownloadMapsWindowMapsListingTest.java @@ -23,10 +23,11 @@ class DownloadMapsWindowMapsListingTest extends AbstractClientSettingTestCase { private static final MapDownloadListing TEST_MAP = MapDownloadListing.builder() .downloadUrl("") + .previewImageUrl("") .mapName(MAP_NAME) .version(MAP_VERSION) - .mapCategory("EXPERIMENTAL") .description("description") + .lastCommitDateEpochMilli(10L) .build(); @Test @@ -61,20 +62,22 @@ void testAvailableExcluding() { private static MapDownloadListing newDownloadWithUrl(final String url) { return MapDownloadListing.builder() .downloadUrl(url) + .previewImageUrl(url) .description("description") .mapName("mapName " + url) .version(MAP_VERSION) - .mapCategory("BEST") + .lastCommitDateEpochMilli(40L) .build(); } private static MapDownloadListing newInstalledDownloadWithUrl(final String url) { return MapDownloadListing.builder() .downloadUrl(url) + .previewImageUrl(url) .description("description") .mapName("mapName " + url) .version(MAP_VERSION) - .mapCategory("BEST") + .lastCommitDateEpochMilli(30L) .build(); } diff --git a/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/listing/MapDownloadListing.java b/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/listing/MapDownloadListing.java index f1f0eb50ba5..1af334c350d 100644 --- a/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/listing/MapDownloadListing.java +++ b/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/listing/MapDownloadListing.java @@ -1,24 +1,44 @@ package org.triplea.http.client.maps.listing; +import java.util.List; import javax.annotation.Nonnull; import lombok.AllArgsConstructor; import lombok.Builder; +import lombok.EqualsAndHashCode; import lombok.Getter; +import lombok.ToString; @Builder @AllArgsConstructor @Getter +@ToString +@EqualsAndHashCode public class MapDownloadListing { /** URL where the map can be downloaded. */ @Nonnull private final String downloadUrl; /** URL of the preview image of the map. */ - private final String previewImageUrl; + @Nonnull private final String previewImageUrl; @Nonnull private final String mapName; - private final Long lastCommitDateEpochMilli; - @Nonnull private final String mapCategory; + @Nonnull private final Long lastCommitDateEpochMilli; /** HTML description of the map. */ @Nonnull private final String description; /** @deprecated use lastCommitDateEpochMilli and file time stamps instead. */ @Deprecated private final Integer version; + + /** Mapping of {tag name -> tag value} */ + private final List mapTags; + + /** + * Finds a tag by name and returns its corresponding value. If the tag is not found or has a null + * value, an empty string is returned instead. + */ + @Nonnull + public String getTagValue(final String tagName) { + return mapTags.stream() + .filter(tag -> tag.getName().equalsIgnoreCase(tagName)) + .findAny() + .map(MapTag::getValue) + .orElse(""); + } } diff --git a/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/listing/MapTag.java b/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/listing/MapTag.java new file mode 100644 index 00000000000..36c3641bb48 --- /dev/null +++ b/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/listing/MapTag.java @@ -0,0 +1,37 @@ +package org.triplea.http.client.maps.listing; + +import java.util.Optional; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Value; + +@Value +@Builder +@EqualsAndHashCode +public class MapTag { + /** The human readable name of the tag */ + String name; + + /** The actual value of the tag */ + String value; + + /** + * Tag type determines how the value is interpreted and rendered. The value should be an element + * of {@code MapTagType} + */ + String type; + + /** + * The ordering to display this map tag in relative to other map tags. Lower values should be + * displayed first. displayOrder is greater than zero. + */ + int displayOrder; + + // public MapTagType getType() { + // return MapTagType.valueOf(type); + // } + + public String getValue() { + return Optional.ofNullable(value).orElse(""); + } +} diff --git a/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/listing/MapTagType.java b/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/listing/MapTagType.java new file mode 100644 index 00000000000..b26ade0bfc2 --- /dev/null +++ b/http-clients/lobby-client/src/main/java/org/triplea/http/client/maps/listing/MapTagType.java @@ -0,0 +1,28 @@ +package org.triplea.http.client.maps.listing; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class MapTagType { + public static final MapTagType STRING = new MapTagType("STRING"); + public static final MapTagType STAR = new MapTagType("STAR"); + + private final String name; + + @Override + public String toString() { + return name; + } + + public static MapTagType valueOf(final String mapTagName) { + if (STAR.name.equalsIgnoreCase(mapTagName)) { + return STAR; + } else { + // default type is STRING. Default is in place to allow older clients to handle newer types. + return STRING; + } + } +} diff --git a/http-clients/lobby-client/src/test/java/org/triplea/http/client/maps/listing/MapsListingClientTest.java b/http-clients/lobby-client/src/test/java/org/triplea/http/client/maps/listing/MapsListingClientTest.java new file mode 100644 index 00000000000..71d9e78a962 --- /dev/null +++ b/http-clients/lobby-client/src/test/java/org/triplea/http/client/maps/listing/MapsListingClientTest.java @@ -0,0 +1,59 @@ +package org.triplea.http.client.maps.listing; + +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.client.WireMock; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.triplea.http.client.WireMockTest; +import org.triplea.test.common.JsonUtil; +import ru.lanwen.wiremock.ext.WiremockResolver; + +class MapsListingClientTest extends WireMockTest { + + private static final List mapsListingResponse = + List.of( + MapDownloadListing.builder() + .mapName("map-1") + .description("description-1") + .downloadUrl("http://download-url") + .previewImageUrl("http://preview-url") + .lastCommitDateEpochMilli(10L) + .build(), + MapDownloadListing.builder() + .mapName("map-2") + .description("description-2") + .downloadUrl("http://download-url-2") + .previewImageUrl("http://preview-url-2") + .lastCommitDateEpochMilli(20L) + .mapTags( + List.of( + MapTag.builder() + .type("STRING") + .displayOrder(1) + .name("tag-name") + .value("tag-value") + .build())) + .build()); + + private static MapsListingClient newClient(final WireMockServer wireMockServer) { + return newClient(wireMockServer, MapsListingHttpClient::new); + } + + @Test + void sendGameHostingRequest(@WiremockResolver.Wiremock final WireMockServer wireMockServer) { + wireMockServer.stubFor( + get(MapsListingClient.MAPS_LISTING_PATH) + .willReturn( + WireMock.aResponse() + .withStatus(200) + .withBody(JsonUtil.toJson(mapsListingResponse)))); + + final var result = newClient(wireMockServer).fetchMapDownloads(); + + assertThat(result, is(mapsListingResponse)); + } +} diff --git a/spitfire-server/database/sql/sample_data/lobby_db_sample_data.sql b/spitfire-server/database/sql/sample_data/lobby_db_sample_data.sql index c283dd6b985..cdd967f92ff 100644 --- a/spitfire-server/database/sql/sample_data/lobby_db_sample_data.sql +++ b/spitfire-server/database/sql/sample_data/lobby_db_sample_data.sql @@ -10,15 +10,22 @@ delete from access_log; delete from user_role; +delete +from map_index; +delete +from map_tag_values; +delete +from tag_type; + insert into user_role(id, name) -values (1, 'ADMIN'), -- user can add/remove admins and add/remove moderators, has boot/ban privileges +values (1, 'ADMIN'), -- user can add/remove admins and add/remove moderators, has boot/ban privileges (2, 'MODERATOR'), -- user has boot/ban privileges - (3, 'PLAYER'), -- standard registered user + (3, 'PLAYER'), -- standard registered user (4, 'ANONYMOUS'), -- users that are not registered, they do not have an entry in lobby_user table (5, 'HOST'); -- AKA LobbyWatcher, special connection for hosts to send game updates to lobby -insert into lobby_user(id, username, email, user_role_id, bcrypt_password) +insert into lobby_user(id, username, email, user_role_id, bcrypt_password) values (1000, 'test', 'email@email.com', (select id from user_role where name = 'ADMIN'), '$2a$10$Ut3tvElEhPPr4s5wPd4dFuOvY25fa4r5XH3T7ucFTr5gJsotZl5d6'), -- password = 'test' (1001, 'user1', 'email@email.com', (select id from user_role where name = 'PLAYER'), @@ -82,3 +89,19 @@ values (1000, 'ACTION_1', 'TARGET_1'), (1000, 'ACTION_48', 'TARGET_48'), (1000, 'ACTION_49', 'TARGET_49'), (1000, 'ACTION_50', 'TARGET_50'); + +insert into map_index +(id, map_name, last_commit_date, repo_url, + description, download_size_bytes, download_url, + preview_image_url) +values (1, 'test-map', now() - interval '1 days', 'http://repo-url', + 'map description', 1024, 'http://download-url', + 'http://preview-image'); + +insert into tag_type (id, name, type, display_order) +values (1, 'Category', 'STRING', 1), + (2, 'Rating', 'STAR', 2); + +insert into map_tag_values (map_id, tag_type_id, tag_value) +values (1, 1, 'BEST'), + (1, 2, '5'); diff --git a/spitfire-server/database/src/main/resources/db/migration/lobby_db/V2.01.01__maps_index_tables.sql b/spitfire-server/database/src/main/resources/db/migration/lobby_db/V2.01.01__maps_index_tables.sql index 1a6c990bc46..a2defd3a6f3 100644 --- a/spitfire-server/database/src/main/resources/db/migration/lobby_db/V2.01.01__maps_index_tables.sql +++ b/spitfire-server/database/src/main/resources/db/migration/lobby_db/V2.01.01__maps_index_tables.sql @@ -1,25 +1,33 @@ -create table map_category -( - id serial primary key, - name varchar(32) unique not null check (length(name) > 2), - date_created timestamptz not null default now() -); - -insert into map_category (name) -values ('BEST'), - ('GOOD'), - ('EXPERIMENTAL'); - create table map_index ( id serial primary key, map_name varchar(256) not null, last_commit_date timestamptz not null check (last_commit_date < now()), repo_url varchar(256) not null unique check (repo_url like 'http%'), - category_id integer not null references map_category (id), + preview_image_url varchar(256) not null check (repo_url like 'http%'), description varchar(3000) not null, download_size_bytes integer not null, download_url varchar(256) not null unique check (download_url like 'http%'), date_created timestamptz not null default now(), date_updated timestamptz not null default now() ); + +create table tag_type +( + id int primary key, + name varchar(64) not null unique, + type varchar(32) not null, + -- disallow display_order values over 1000, we do not expect nearly that many unique tag types + display_order int not null unique check (display_order >= 0 and display_order < 1000) +); + +create table map_tag_values +( + id serial primary key, + map_id integer references map_index (id), + tag_type_id integer references tag_type (id), + tag_value varchar(128) not null +); + +alter table map_tag_values + add constraint map_id__tag_id__is__unique unique (map_id, tag_type_id); diff --git a/spitfire-server/dropwizard-server/src/test/java/org/triplea/maps/listing/MapsListingControllerTest.java b/spitfire-server/dropwizard-server/src/test/java/org/triplea/maps/listing/MapsListingControllerTest.java deleted file mode 100644 index f534b3a9df9..00000000000 --- a/spitfire-server/dropwizard-server/src/test/java/org/triplea/maps/listing/MapsListingControllerTest.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.triplea.maps.listing; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.collection.IsCollectionWithSize.hasSize; -import static org.hamcrest.core.Is.is; - -import com.github.database.rider.core.api.dataset.DataSet; -import java.net.URI; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneOffset; -import java.util.List; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.triplea.http.client.maps.listing.MapDownloadListing; -import org.triplea.http.client.maps.listing.MapsListingClient; -import org.triplea.http.client.maps.listing.MapsListingHttpClient; -import org.triplea.spitfire.server.SpitfireServerTest; - -@SuppressWarnings("UnmatchedTest") -@Disabled -@DataSet(value = "map_category.yml,map_index.yml", useSequenceFiltering = false) -class MapsListingControllerTest extends SpitfireServerTest { - private static final Instant commitDate1 = - LocalDateTime.of(2000, 12, 1, 23, 59, 20).toInstant(ZoneOffset.UTC); - private static final Instant commitDate2 = - LocalDateTime.of(2016, 1, 1, 23, 59, 20).toInstant(ZoneOffset.UTC); - - private final MapsListingClient mapsListingClient; - - MapsListingControllerTest(final URI serverUri) { - mapsListingClient = new MapsListingHttpClient(serverUri); - } - - @Test - void verifyMapListingEndpoint() { - final List downloadListings = mapsListingClient.fetchMapDownloads(); - - assertThat(downloadListings, hasSize(2)); - assertThat(downloadListings.get(0).getMapName(), is("map-name")); - assertThat( - downloadListings.get(0).getLastCommitDateEpochMilli(), is(commitDate1.toEpochMilli())); - assertThat(downloadListings.get(0).getDownloadUrl(), is("http://map-repo-url")); - assertThat(downloadListings.get(0).getMapCategory(), is("category_name")); - - assertThat(downloadListings.get(1).getMapName(), is("map-name-2")); - assertThat( - downloadListings.get(1).getLastCommitDateEpochMilli(), is(commitDate2.toEpochMilli())); - assertThat(downloadListings.get(1).getDownloadUrl(), is("http://map-repo-url-2")); - assertThat(downloadListings.get(1).getMapCategory(), is("category_name")); - } -} diff --git a/spitfire-server/dropwizard-server/src/test/java/org/triplea/spitfire/server/maps/MapsListingControllerTest.java b/spitfire-server/dropwizard-server/src/test/java/org/triplea/spitfire/server/maps/MapsListingControllerTest.java new file mode 100644 index 00000000000..784b5cc8c82 --- /dev/null +++ b/spitfire-server/dropwizard-server/src/test/java/org/triplea/spitfire/server/maps/MapsListingControllerTest.java @@ -0,0 +1,53 @@ +package org.triplea.spitfire.server.maps; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsNull.notNullValue; + +import com.github.database.rider.core.api.dataset.DataSet; +import com.github.database.rider.junit5.DBUnitExtension; +import java.net.URI; +import lombok.AllArgsConstructor; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.triplea.http.client.maps.listing.MapsListingHttpClient; +import org.triplea.spitfire.server.SpitfireServerTestExtension; + +@AllArgsConstructor +@ExtendWith(SpitfireServerTestExtension.class) +@ExtendWith(DBUnitExtension.class) +@DataSet(value = "map_index.yml,map_tag_values.yml", useSequenceFiltering = false) +class MapsListingControllerTest { + private final URI localhost; + + /** Invoke the maps listing endpoint and verify response data is present. */ + @Test + void invokeMapsListingEndpoint() { + final var result = new MapsListingHttpClient(localhost).fetchMapDownloads(); + + assertThat(result, hasSize(2)); + for (int i = 0; i < 2; i++) { + assertThat(result.get(i).getDescription(), is(notNullValue())); + assertThat(result.get(i).getMapName(), is(notNullValue())); + assertThat(result.get(i).getDownloadUrl(), is(notNullValue())); + assertThat(result.get(i).getLastCommitDateEpochMilli(), is(notNullValue())); + assertThat(result.get(i).getPreviewImageUrl(), is(notNullValue())); + } + assertThat(result.get(0).getMapTags(), hasSize(2)); + assertThat( + "Verify tags are sorted by display order", + result.get(0).getMapTags().get(0).getDisplayOrder() + < result.get(0).getMapTags().get(1).getDisplayOrder(), + is(true)); + + assertThat(result.get(1).getMapTags(), hasSize(1)); + assertThat(result.get(1).getMapTags().get(0).getName(), is(notNullValue())); + assertThat(result.get(1).getMapTags().get(0).getType(), is(notNullValue())); + assertThat(result.get(1).getMapTags().get(0).getValue(), is(notNullValue())); + assertThat( + "Display order should always be a positive value", + result.get(1).getMapTags().get(0).getDisplayOrder() > 0, + is(true)); + } +} diff --git a/spitfire-server/dropwizard-server/src/test/resources/db-cleanup.sql b/spitfire-server/dropwizard-server/src/test/resources/db-cleanup.sql new file mode 100644 index 00000000000..80cd0885680 --- /dev/null +++ b/spitfire-server/dropwizard-server/src/test/resources/db-cleanup.sql @@ -0,0 +1,16 @@ +-- Deletes table data in proper order + +delete from access_log; +delete from bad_word; +delete from banned_user; +delete from banned_username; +delete from game_chat_history; +delete from lobby_game; +delete from game_hosting_api_key; +delete from lobby_chat_history; +delete from lobby_api_key; +delete from moderator_action_history; +delete from temp_password_request; +delete from temp_password_request_history; +delete from lobby_user; +delete from user_role; diff --git a/spitfire-server/dropwizard-server/src/test/resources/map_index.yml b/spitfire-server/dropwizard-server/src/test/resources/map_index.yml new file mode 100644 index 00000000000..cf32b3217b9 --- /dev/null +++ b/spitfire-server/dropwizard-server/src/test/resources/map_index.yml @@ -0,0 +1,19 @@ +map_index: + - id: 10 + map_name: map-name + # Do not use "http:" in test data, DB rider logs a noisy warning about this. + # repo_url must otherwise begin with 'http' per column constraint + repo_url: 'http-map-repo-url' + description: description-repo-1 + download_url: 'http-map-repo-url/archives/master.zip' + preview_image_url: 'http-preview-image-url' + download_size_bytes: 4000 + last_commit_date: 2000-12-01 23:59:20.0 + - id: 20 + map_name: map-name-2 + repo_url: 'http-map-repo-url-2' + description: description-repo-2 + download_url: 'http-map-repo-url-2/archives/master.zip' + preview_image_url: 'http-preview-image-url-2' + download_size_bytes: 1000 + last_commit_date: 2016-01-01 23:59:20.0 diff --git a/spitfire-server/dropwizard-server/src/test/resources/map_tag_values.yml b/spitfire-server/dropwizard-server/src/test/resources/map_tag_values.yml new file mode 100644 index 00000000000..88d209e2f6e --- /dev/null +++ b/spitfire-server/dropwizard-server/src/test/resources/map_tag_values.yml @@ -0,0 +1,23 @@ +tag_type: + - id: 0 + name: Category + type: STRING + display_order: 1 + - id: 1 + name: Rating + type: STAR + display_order: 2 + +map_tag_values: + - id: 0 + map_id: 10 + tag_type_id: 0 + tag_value: Best + - id: 1 + map_id: 10 + tag_type_id: 1 + tag_value: 5 + - id: 2 + map_id: 20 + tag_type_id: 0 + tag_value: New diff --git a/spitfire-server/maps-module/src/main/java/org/triplea/maps/MapsModuleRowMappers.java b/spitfire-server/maps-module/src/main/java/org/triplea/maps/MapsModuleRowMappers.java index 60632d8765a..20556e115a5 100644 --- a/spitfire-server/maps-module/src/main/java/org/triplea/maps/MapsModuleRowMappers.java +++ b/spitfire-server/maps-module/src/main/java/org/triplea/maps/MapsModuleRowMappers.java @@ -5,6 +5,7 @@ import org.jdbi.v3.core.mapper.RowMapperFactory; import org.jdbi.v3.core.mapper.reflect.ConstructorMapper; import org.triplea.maps.listing.MapListingRecord; +import org.triplea.maps.listing.MapTagRecord; /** Utility to get connections to the Postgres lobby database. */ @UtilityClass @@ -14,6 +15,9 @@ public final class MapsModuleRowMappers { * objects. */ public static List rowMappers() { - return List.of(ConstructorMapper.factory(MapListingRecord.class)); + return List.of( + ConstructorMapper.factory(MapListingRecord.class), + ConstructorMapper.factory(MapTagRecord.class) // + ); } } diff --git a/spitfire-server/maps-module/src/main/java/org/triplea/maps/indexing/MapIndexDao.java b/spitfire-server/maps-module/src/main/java/org/triplea/maps/indexing/MapIndexDao.java index f07372ff8d0..64a3914e0c5 100644 --- a/spitfire-server/maps-module/src/main/java/org/triplea/maps/indexing/MapIndexDao.java +++ b/spitfire-server/maps-module/src/main/java/org/triplea/maps/indexing/MapIndexDao.java @@ -14,16 +14,17 @@ public interface MapIndexDao { /** Upserts a map indexing result into the map_index table. */ @SqlUpdate( "insert into map_index(" - + " map_name, repo_url, category_id, description, " - + " download_url, download_size_bytes, last_commit_date)\n" + + " map_name, repo_url, description, " + + " download_url, preview_image_url, download_size_bytes, last_commit_date)\n" + "values(" - + " :mapName, :mapRepoUri, 1, :description, " - + " :downloadUri, :mapDownloadSizeInBytes, :lastCommitDate)\n" + + " :mapName, :mapRepoUri, :description, " + + " :downloadUri, :previewImageUri, :mapDownloadSizeInBytes, :lastCommitDate)\n" + "on conflict(repo_url)\n" + "do update set\n" + " map_name = :mapName," + " description = :description," + " download_url = :downloadUri," + + " preview_image_url = :previewImageUri," + " download_size_bytes = :mapDownloadSizeInBytes," + " last_commit_date = :lastCommitDate") void upsert(@BindBean MapIndexingResult mapIndexingResult); diff --git a/spitfire-server/maps-module/src/main/java/org/triplea/maps/indexing/MapIndexingResult.java b/spitfire-server/maps-module/src/main/java/org/triplea/maps/indexing/MapIndexingResult.java index 9a00806a32e..1bd40638838 100644 --- a/spitfire-server/maps-module/src/main/java/org/triplea/maps/indexing/MapIndexingResult.java +++ b/spitfire-server/maps-module/src/main/java/org/triplea/maps/indexing/MapIndexingResult.java @@ -24,6 +24,12 @@ public class MapIndexingResult { */ @Nonnull String downloadUri; + /** + * URI to download preview image, eg: + * https://raw.githubusercontent.com/triplea-maps/napoleonic_empires/master/preview.png + */ + @Nonnull String previewImageUri; + /** The size of the map download in bytes. */ @Nonnull Long mapDownloadSizeInBytes; diff --git a/spitfire-server/maps-module/src/main/java/org/triplea/maps/indexing/MapIndexingTask.java b/spitfire-server/maps-module/src/main/java/org/triplea/maps/indexing/MapIndexingTask.java index 7cd4657d81f..a9ca20619f5 100644 --- a/spitfire-server/maps-module/src/main/java/org/triplea/maps/indexing/MapIndexingTask.java +++ b/spitfire-server/maps-module/src/main/java/org/triplea/maps/indexing/MapIndexingTask.java @@ -8,6 +8,7 @@ import lombok.Builder; import org.triplea.http.client.github.MapRepoListing; import org.triplea.maps.indexing.tasks.DownloadUriCalculator; +import org.triplea.maps.indexing.tasks.PreviewUriCalculator; /** * Given a map repo name and URI, reads pertinent indexing information. Indexing will be skipped if @@ -47,6 +48,8 @@ public Optional apply(final MapRepoListing mapRepoListing) { final String downloadUri = new DownloadUriCalculator().apply(mapRepoListing); + final String previewImageUri = new PreviewUriCalculator().apply(mapRepoListing); + final Long downloadSize = downloadSizeFetcher.apply(mapRepoListing).orElse(null); if (downloadSize == null) { return Optional.empty(); @@ -59,6 +62,7 @@ public Optional apply(final MapRepoListing mapRepoListing) { .lastCommitDate(lastCommitDateOnRepo) .description(description) .downloadUri(downloadUri) + .previewImageUri(previewImageUri) .mapDownloadSizeInBytes(downloadSize) .build()); } diff --git a/spitfire-server/maps-module/src/main/java/org/triplea/maps/indexing/tasks/PreviewUriCalculator.java b/spitfire-server/maps-module/src/main/java/org/triplea/maps/indexing/tasks/PreviewUriCalculator.java new file mode 100644 index 00000000000..90102103f5b --- /dev/null +++ b/spitfire-server/maps-module/src/main/java/org/triplea/maps/indexing/tasks/PreviewUriCalculator.java @@ -0,0 +1,11 @@ +package org.triplea.maps.indexing.tasks; + +import java.util.function.Function; +import org.triplea.http.client.github.MapRepoListing; + +public class PreviewUriCalculator implements Function { + @Override + public String apply(final MapRepoListing mapRepoListing) { + return mapRepoListing.getUri().toString() + "/blob/master/preview.png?raw=true"; + } +} diff --git a/spitfire-server/maps-module/src/main/java/org/triplea/maps/listing/MapListingDao.java b/spitfire-server/maps-module/src/main/java/org/triplea/maps/listing/MapListingDao.java index 4c51d6ca5b8..b07c8777096 100644 --- a/spitfire-server/maps-module/src/main/java/org/triplea/maps/listing/MapListingDao.java +++ b/spitfire-server/maps-module/src/main/java/org/triplea/maps/listing/MapListingDao.java @@ -1,18 +1,33 @@ package org.triplea.maps.listing; import java.util.List; +import org.jdbi.v3.sqlobject.customizer.Bind; import org.jdbi.v3.sqlobject.statement.SqlQuery; public interface MapListingDao { + /** Returns all maps registered listed in database. */ @SqlQuery( "select" + " m.map_name," - + " m.repo_url," + + " m.download_url," + + " m.preview_image_url," + " m.description," - + " m.last_commit_date," - + " c.name as category_name" + + " m.last_commit_date" + " from map_index m" - + " join map_category c on c.id = m.category_id" + " order by m.map_name") List fetchMapListings(); + + /** Fetchs map tags for a given map. */ + @SqlQuery( + "select" + + " tt.name," + + " tt.type," + + " tt.display_order," + + " mtv.tag_value" + + " from map_tag_values mtv" + + " join tag_type tt on tt.id = mtv.tag_type_id" + + " join map_index mi on mi.id = mtv.map_id" + + " where mi.map_name = :mapName" + + " order by tt.display_order") + List fetchMapTagsForMapName(@Bind("mapName") String mapName); } diff --git a/spitfire-server/maps-module/src/main/java/org/triplea/maps/listing/MapListingRecord.java b/spitfire-server/maps-module/src/main/java/org/triplea/maps/listing/MapListingRecord.java index b8fe5debb85..35bf50c029f 100644 --- a/spitfire-server/maps-module/src/main/java/org/triplea/maps/listing/MapListingRecord.java +++ b/spitfire-server/maps-module/src/main/java/org/triplea/maps/listing/MapListingRecord.java @@ -1,38 +1,43 @@ package org.triplea.maps.listing; import java.time.Instant; +import java.util.List; import lombok.Builder; +import lombok.Getter; import org.jdbi.v3.core.mapper.reflect.ColumnName; import org.triplea.http.client.maps.listing.MapDownloadListing; +import org.triplea.http.client.maps.listing.MapTag; +@Getter public class MapListingRecord { private final String name; - private final String url; + private final String downloadUrl; + private final String previewImageUrl; private final String description; private final Instant lastCommitDate; - private final String categoryName; @Builder public MapListingRecord( @ColumnName("map_name") final String name, - @ColumnName("repo_url") final String url, + @ColumnName("download_url") final String downloadUrl, + @ColumnName("preview_image_url") final String previewImageUrl, @ColumnName("description") final String description, - @ColumnName("last_commit_date") final Instant lastCommitDate, - @ColumnName("category_name") final String categoryName) { - this.url = url; + @ColumnName("last_commit_date") final Instant lastCommitDate) { this.name = name; - this.lastCommitDate = lastCommitDate; - this.categoryName = categoryName; + this.downloadUrl = downloadUrl; + this.previewImageUrl = previewImageUrl; this.description = description; + this.lastCommitDate = lastCommitDate; } - MapDownloadListing toMapDownloadListing() { + public MapDownloadListing toMapDownloadItem(final List mapTags) { return MapDownloadListing.builder() - .downloadUrl(url) + .downloadUrl(downloadUrl) + .previewImageUrl(previewImageUrl) .mapName(name) .lastCommitDateEpochMilli(lastCommitDate.toEpochMilli()) - .mapCategory(categoryName) .description(description) + .mapTags(mapTags) .build(); } } diff --git a/spitfire-server/maps-module/src/main/java/org/triplea/maps/listing/MapTagRecord.java b/spitfire-server/maps-module/src/main/java/org/triplea/maps/listing/MapTagRecord.java new file mode 100644 index 00000000000..aa7fc37fc70 --- /dev/null +++ b/spitfire-server/maps-module/src/main/java/org/triplea/maps/listing/MapTagRecord.java @@ -0,0 +1,28 @@ +package org.triplea.maps.listing; + +import lombok.Builder; +import org.jdbi.v3.core.mapper.reflect.ColumnName; +import org.triplea.http.client.maps.listing.MapTag; + +public class MapTagRecord { + private final String name; + private final String value; + private final String type; + private final int displayOrder; + + @Builder + public MapTagRecord( + @ColumnName("name") final String name, + @ColumnName("tag_value") final String value, + @ColumnName("type") final String type, + @ColumnName("display_order") final int displayOrder) { + this.name = name; + this.value = value; + this.type = type; + this.displayOrder = displayOrder; + } + + public MapTag toMapTag() { + return MapTag.builder().name(name).value(value).type(type).displayOrder(displayOrder).build(); + } +} diff --git a/spitfire-server/maps-module/src/main/java/org/triplea/maps/listing/MapsListingModule.java b/spitfire-server/maps-module/src/main/java/org/triplea/maps/listing/MapsListingModule.java index cc596b93440..50d62e5274f 100644 --- a/spitfire-server/maps-module/src/main/java/org/triplea/maps/listing/MapsListingModule.java +++ b/spitfire-server/maps-module/src/main/java/org/triplea/maps/listing/MapsListingModule.java @@ -1,5 +1,6 @@ package org.triplea.maps.listing; +import java.util.Comparator; import java.util.List; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -11,10 +12,24 @@ public class MapsListingModule implements Supplier> { private final MapListingDao mapListingDao; + /** + * Fetch all maps from database, for each fetch map tags from database, combine into a {@code + * MapDownloadItem} and return a sorted list by map name. + */ @Override public List get() { return mapListingDao.fetchMapListings().stream() - .map(MapListingRecord::toMapDownloadListing) + .map(this::databaseRecordToDownloadItemFunction) + .sorted(Comparator.comparing(MapDownloadListing::getMapName)) .collect(Collectors.toList()); } + + private MapDownloadListing databaseRecordToDownloadItemFunction( + final MapListingRecord mapListingRecord) { + final var mapTagsFetchedFromDatabase = + mapListingDao.fetchMapTagsForMapName(mapListingRecord.getName()).stream() + .map(MapTagRecord::toMapTag) + .collect(Collectors.toList()); + return mapListingRecord.toMapDownloadItem(mapTagsFetchedFromDatabase); + } } diff --git a/spitfire-server/maps-module/src/test/java/org/triplea/maps/indexing/MapIndexDaoTest.java b/spitfire-server/maps-module/src/test/java/org/triplea/maps/indexing/MapIndexDaoTest.java index fabb3112f9e..f9dc87fe657 100644 --- a/spitfire-server/maps-module/src/test/java/org/triplea/maps/indexing/MapIndexDaoTest.java +++ b/spitfire-server/maps-module/src/test/java/org/triplea/maps/indexing/MapIndexDaoTest.java @@ -16,7 +16,7 @@ import org.triplea.maps.MapsModuleDatabaseTestSupport; @AllArgsConstructor -@DataSet(value = "map_category.yml,map_index.yml", useSequenceFiltering = false) +@DataSet(value = "map_index.yml", useSequenceFiltering = false) @ExtendWith(MapsModuleDatabaseTestSupport.class) @ExtendWith(DBUnitExtension.class) class MapIndexDaoTest { @@ -33,6 +33,7 @@ void upsertCreatesNewRecords() { .lastCommitDate(LocalDateTime.of(2000, 1, 12, 23, 59).toInstant(ZoneOffset.UTC)) .mapDownloadSizeInBytes(3080L) .downloadUri("http-map-repo-3-download") + .previewImageUri("http-preview-image-url-3") .description("description") .build()); } @@ -47,6 +48,7 @@ void upsertUpdatesRecords() { .lastCommitDate(LocalDateTime.of(2000, 1, 12, 23, 59).toInstant(ZoneOffset.UTC)) .mapDownloadSizeInBytes(6789L) .downloadUri("http-map-repo-3-download-updated-url") + .previewImageUri("http-preview-image-url-3") .description("description-updated") .build()); } @@ -62,6 +64,7 @@ void upsertSameData() { .lastCommitDate(LocalDateTime.of(2016, 1, 1, 23, 59, 20).toInstant(ZoneOffset.UTC)) .mapDownloadSizeInBytes(1000L) .downloadUri("http-map-repo-url-2/archives/master.zip") + .previewImageUri("http-preview-image-url-2") .description("description-repo-2") .build()); } diff --git a/spitfire-server/maps-module/src/test/java/org/triplea/maps/indexing/MapIndexingTaskRunnerTest.java b/spitfire-server/maps-module/src/test/java/org/triplea/maps/indexing/MapIndexingTaskRunnerTest.java index d15d4a7c59e..47d955bb5df 100644 --- a/spitfire-server/maps-module/src/test/java/org/triplea/maps/indexing/MapIndexingTaskRunnerTest.java +++ b/spitfire-server/maps-module/src/test/java/org/triplea/maps/indexing/MapIndexingTaskRunnerTest.java @@ -27,6 +27,7 @@ class MapIndexingTaskRunnerTest { .mapName("map-name") .mapRepoUri("http://repo") .downloadUri("http://repo-download") + .previewImageUri("http://preview") .mapDownloadSizeInBytes(555L) .description("description") .build(); diff --git a/spitfire-server/maps-module/src/test/java/org/triplea/maps/indexing/tasks/PreviewUriCalculatorTest.java b/spitfire-server/maps-module/src/test/java/org/triplea/maps/indexing/tasks/PreviewUriCalculatorTest.java new file mode 100644 index 00000000000..2209e5ea55d --- /dev/null +++ b/spitfire-server/maps-module/src/test/java/org/triplea/maps/indexing/tasks/PreviewUriCalculatorTest.java @@ -0,0 +1,23 @@ +package org.triplea.maps.indexing.tasks; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; + +import org.junit.jupiter.api.Test; +import org.triplea.http.client.github.MapRepoListing; + +class PreviewUriCalculatorTest { + @Test + void verifyDownloadUriCalculation() { + final var mapRepoListing = + MapRepoListing.builder() + .htmlUrl("https://github.com/triplea-maps/test-map") + .name("repo name") + .build(); + + final String result = new PreviewUriCalculator().apply(mapRepoListing); + + assertThat( + result, is("https://github.com/triplea-maps/test-map/blob/master/preview.png?raw=true")); + } +} diff --git a/spitfire-server/maps-module/src/test/java/org/triplea/maps/listing/MapListingDaoTest.java b/spitfire-server/maps-module/src/test/java/org/triplea/maps/listing/MapListingDaoTest.java index 23513c9a88a..4be061d4b84 100644 --- a/spitfire-server/maps-module/src/test/java/org/triplea/maps/listing/MapListingDaoTest.java +++ b/spitfire-server/maps-module/src/test/java/org/triplea/maps/listing/MapListingDaoTest.java @@ -8,11 +8,12 @@ import com.github.database.rider.junit5.DBUnitExtension; import java.time.LocalDateTime; import java.time.ZoneOffset; +import java.util.stream.Collectors; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.triplea.maps.MapsModuleDatabaseTestSupport; -@DataSet(value = "map_category.yml,map_index.yml", useSequenceFiltering = false) +@DataSet(value = "map_index.yml,map_tag_values.yml", useSequenceFiltering = false) @ExtendWith(MapsModuleDatabaseTestSupport.class) @ExtendWith(DBUnitExtension.class) class MapListingDaoTest { @@ -26,15 +27,42 @@ class MapListingDaoTest { @Test void verifySelect() { final var results = mapListingDao.fetchMapListings(); - assertThat(results, hasSize(2)); - final var mapDownloadListing = results.get(0).toMapDownloadListing(); - assertThat(mapDownloadListing.getMapCategory(), is("category_name")); - assertThat(mapDownloadListing.getMapName(), is("map-name")); - assertThat(mapDownloadListing.getDownloadUrl(), is("http-map-repo-url")); + final var mapDownloadListing = results.get(0); + assertThat(mapDownloadListing.getName(), is("map-name")); + assertThat(mapDownloadListing.getDownloadUrl(), is("http-map-repo-url/archives/master.zip")); + assertThat(mapDownloadListing.getPreviewImageUrl(), is("http-preview-image-url")); assertThat(mapDownloadListing.getDescription(), is("description-repo-1")); assertThat( - mapDownloadListing.getLastCommitDateEpochMilli(), + mapDownloadListing.getLastCommitDate().toEpochMilli(), is(LocalDateTime.of(2000, 12, 1, 23, 59, 20).toInstant(ZoneOffset.UTC).toEpochMilli())); } + + @Test + void verifyFetchMapTags() { + var mapTags = + mapListingDao.fetchMapTagsForMapName("map-name").stream() + .map(MapTagRecord::toMapTag) + .collect(Collectors.toList()); + assertThat(mapTags, hasSize(2)); + assertThat(mapTags.get(0).getName(), is("Category")); + assertThat(mapTags.get(0).getType(), is("STRING")); + assertThat(mapTags.get(0).getDisplayOrder(), is(1)); + assertThat(mapTags.get(0).getValue(), is("Best")); + + assertThat(mapTags.get(1).getName(), is("Rating")); + assertThat(mapTags.get(1).getType(), is("STAR")); + assertThat(mapTags.get(1).getDisplayOrder(), is(2)); + assertThat(mapTags.get(1).getValue(), is("5")); + + mapTags = + mapListingDao.fetchMapTagsForMapName("map-name-2").stream() + .map(MapTagRecord::toMapTag) + .collect(Collectors.toList()); + assertThat(mapTags, hasSize(1)); + assertThat(mapTags.get(0).getName(), is("Category")); + assertThat(mapTags.get(0).getType(), is("STRING")); + assertThat(mapTags.get(0).getDisplayOrder(), is(1)); + assertThat(mapTags.get(0).getValue(), is("New")); + } } diff --git a/spitfire-server/maps-module/src/test/java/org/triplea/maps/listing/MapsListingModuleTest.java b/spitfire-server/maps-module/src/test/java/org/triplea/maps/listing/MapsListingModuleTest.java index 6c2a875543d..631e45907d9 100644 --- a/spitfire-server/maps-module/src/test/java/org/triplea/maps/listing/MapsListingModuleTest.java +++ b/spitfire-server/maps-module/src/test/java/org/triplea/maps/listing/MapsListingModuleTest.java @@ -36,17 +36,17 @@ void verifyDataFetch() { .thenReturn( List.of( MapListingRecord.builder() - .url("http://map-url-1") + .downloadUrl("http://map-url-1") + .previewImageUrl("http-preview-url-1") .name("map-name-1") .lastCommitDate(commitDate1) - .categoryName("category-1") .description("description-1") .build(), MapListingRecord.builder() - .url("http://map-url-2") + .downloadUrl("http://map-url-2") + .previewImageUrl("http-preview-url-2") .name("map-name-2") .lastCommitDate(commitDate2) - .categoryName("category-2") .description("description-1") .build())); @@ -56,11 +56,11 @@ void verifyDataFetch() { assertThat(results.get(0).getMapName(), is("map-name-1")); assertThat(results.get(0).getLastCommitDateEpochMilli(), is(commitDate1.toEpochMilli())); assertThat(results.get(0).getDownloadUrl(), is("http://map-url-1")); - assertThat(results.get(0).getMapCategory(), is("category-1")); + assertThat(results.get(0).getPreviewImageUrl(), is("http-preview-url-1")); assertThat(results.get(1).getMapName(), is("map-name-2")); assertThat(results.get(1).getLastCommitDateEpochMilli(), is(commitDate2.toEpochMilli())); assertThat(results.get(1).getDownloadUrl(), is("http://map-url-2")); - assertThat(results.get(1).getMapCategory(), is("category-2")); + assertThat(results.get(1).getPreviewImageUrl(), is("http-preview-url-2")); } } diff --git a/spitfire-server/maps-module/src/test/resources/datasets/expected/map_index_post_remove.yml b/spitfire-server/maps-module/src/test/resources/datasets/expected/map_index_post_remove.yml index d1fa1bab558..b0a37ea4422 100644 --- a/spitfire-server/maps-module/src/test/resources/datasets/expected/map_index_post_remove.yml +++ b/spitfire-server/maps-module/src/test/resources/datasets/expected/map_index_post_remove.yml @@ -2,5 +2,4 @@ map_index: - id: 10 map_name: map-name repo_url: "http-map-repo-url" - category_id: 1 last_commit_date: 2000-12-01 23:59:20.0 diff --git a/spitfire-server/maps-module/src/test/resources/datasets/expected/map_index_upsert_new.yml b/spitfire-server/maps-module/src/test/resources/datasets/expected/map_index_upsert_new.yml index 1b8aaae4afd..99b1db3ef54 100644 --- a/spitfire-server/maps-module/src/test/resources/datasets/expected/map_index_upsert_new.yml +++ b/spitfire-server/maps-module/src/test/resources/datasets/expected/map_index_upsert_new.yml @@ -3,17 +3,20 @@ map_index: repo_url: "http-map-repo-url" description: description-repo-1 download_url: 'http-map-repo-url/archives/master.zip' + preview_image_url: 'http-preview-image-url' download_size_bytes: 4000 last_commit_date: 2000-12-01 23:59:20.0 - map_name: map-name-2 repo_url: "http-map-repo-url-2" description: description-repo-2 download_url: 'http-map-repo-url-2/archives/master.zip' + preview_image_url: 'http-preview-image-url-2' download_size_bytes: 1000 last_commit_date: 2016-01-01 23:59:20.0 - map_name: map-name-3 repo_url: "http-map-repo-url-3" description: description download_url: 'http-map-repo-3-download' + preview_image_url: 'http-preview-image-url-3' download_size_bytes: 3080 last_commit_date: 2000-01-12 23:59:00.0 diff --git a/spitfire-server/maps-module/src/test/resources/datasets/expected/map_index_upsert_updated.yml b/spitfire-server/maps-module/src/test/resources/datasets/expected/map_index_upsert_updated.yml index 5864d1fee1a..2719eb69414 100644 --- a/spitfire-server/maps-module/src/test/resources/datasets/expected/map_index_upsert_updated.yml +++ b/spitfire-server/maps-module/src/test/resources/datasets/expected/map_index_upsert_updated.yml @@ -2,16 +2,16 @@ map_index: - id: 10 map_name: map-name repo_url: 'http-map-repo-url' - category_id: 1 description: description-repo-1 download_url: 'http-map-repo-url/archives/master.zip' + preview_image_url: 'http-preview-image-url' download_size_bytes: 4000 last_commit_date: 2000-12-01 23:59:20.0 - id: 20 map_name: map-name-updated repo_url: "http-map-repo-url-2" - category_id: 1 description: description-updated download_url: 'http-map-repo-3-download-updated-url' + preview_image_url: 'http-preview-image-url-3' download_size_bytes: 6789 last_commit_date: 2000-01-12 23:59:00.0 diff --git a/spitfire-server/maps-module/src/test/resources/datasets/map_category.yml b/spitfire-server/maps-module/src/test/resources/datasets/map_category.yml deleted file mode 100644 index 6cc6a9f8875..00000000000 --- a/spitfire-server/maps-module/src/test/resources/datasets/map_category.yml +++ /dev/null @@ -1,3 +0,0 @@ -map_category: - - id: 1 - name: category_name diff --git a/spitfire-server/maps-module/src/test/resources/datasets/map_index.yml b/spitfire-server/maps-module/src/test/resources/datasets/map_index.yml index 7f6f1d71cdd..cf32b3217b9 100644 --- a/spitfire-server/maps-module/src/test/resources/datasets/map_index.yml +++ b/spitfire-server/maps-module/src/test/resources/datasets/map_index.yml @@ -4,16 +4,16 @@ map_index: # Do not use "http:" in test data, DB rider logs a noisy warning about this. # repo_url must otherwise begin with 'http' per column constraint repo_url: 'http-map-repo-url' - category_id: 1 description: description-repo-1 download_url: 'http-map-repo-url/archives/master.zip' + preview_image_url: 'http-preview-image-url' download_size_bytes: 4000 last_commit_date: 2000-12-01 23:59:20.0 - id: 20 map_name: map-name-2 repo_url: 'http-map-repo-url-2' - category_id: 1 description: description-repo-2 download_url: 'http-map-repo-url-2/archives/master.zip' + preview_image_url: 'http-preview-image-url-2' download_size_bytes: 1000 last_commit_date: 2016-01-01 23:59:20.0 diff --git a/spitfire-server/maps-module/src/test/resources/datasets/map_tag_values.yml b/spitfire-server/maps-module/src/test/resources/datasets/map_tag_values.yml new file mode 100644 index 00000000000..88d209e2f6e --- /dev/null +++ b/spitfire-server/maps-module/src/test/resources/datasets/map_tag_values.yml @@ -0,0 +1,23 @@ +tag_type: + - id: 0 + name: Category + type: STRING + display_order: 1 + - id: 1 + name: Rating + type: STAR + display_order: 2 + +map_tag_values: + - id: 0 + map_id: 10 + tag_type_id: 0 + tag_value: Best + - id: 1 + map_id: 10 + tag_type_id: 1 + tag_value: 5 + - id: 2 + map_id: 20 + tag_type_id: 0 + tag_value: New diff --git a/spitfire-server/maps-module/src/test/resources/db-cleanup.sql b/spitfire-server/maps-module/src/test/resources/db-cleanup.sql index a1ae3614a47..a2c038b6f77 100644 --- a/spitfire-server/maps-module/src/test/resources/db-cleanup.sql +++ b/spitfire-server/maps-module/src/test/resources/db-cleanup.sql @@ -1,4 +1,5 @@ -- Deletes table data in proper order +delete from map_tag_values; +delete from tag_type; delete from map_index; -delete from map_category;