diff --git a/core/src/main/java/google/registry/module/backend/BackendRequestComponent.java b/core/src/main/java/google/registry/module/backend/BackendRequestComponent.java index 0f65a5d0d14..9f474f6bfe2 100644 --- a/core/src/main/java/google/registry/module/backend/BackendRequestComponent.java +++ b/core/src/main/java/google/registry/module/backend/BackendRequestComponent.java @@ -99,7 +99,7 @@ VoidDnsWriterModule.class, WhiteboxModule.class, }) -interface BackendRequestComponent { +public interface BackendRequestComponent { BrdaCopyAction brdaCopyAction(); diff --git a/core/src/main/java/google/registry/module/bsa/BsaRequestComponent.java b/core/src/main/java/google/registry/module/bsa/BsaRequestComponent.java index 1c706f72cb9..36c34874b12 100644 --- a/core/src/main/java/google/registry/module/bsa/BsaRequestComponent.java +++ b/core/src/main/java/google/registry/module/bsa/BsaRequestComponent.java @@ -27,7 +27,7 @@ @RequestScope @Subcomponent(modules = {RequestModule.class, UrlConnectionServiceModule.class}) -interface BsaRequestComponent { +public interface BsaRequestComponent { BsaDownloadAction bsaDownloadAction(); diff --git a/core/src/main/java/google/registry/module/frontend/FrontendRequestComponent.java b/core/src/main/java/google/registry/module/frontend/FrontendRequestComponent.java index 4204683beb5..33cbeeeecdd 100644 --- a/core/src/main/java/google/registry/module/frontend/FrontendRequestComponent.java +++ b/core/src/main/java/google/registry/module/frontend/FrontendRequestComponent.java @@ -53,7 +53,7 @@ RequestModule.class, WhiteboxModule.class, }) -interface FrontendRequestComponent { +public interface FrontendRequestComponent { ConsoleDomainGetAction consoleDomainGetAction(); ConsoleDomainListAction consoleDomainListAction(); diff --git a/core/src/main/java/google/registry/module/pubapi/PubApiRequestComponent.java b/core/src/main/java/google/registry/module/pubapi/PubApiRequestComponent.java index be2017d0a2f..30d1ab205f2 100644 --- a/core/src/main/java/google/registry/module/pubapi/PubApiRequestComponent.java +++ b/core/src/main/java/google/registry/module/pubapi/PubApiRequestComponent.java @@ -50,7 +50,7 @@ WhiteboxModule.class, WhoisModule.class, }) -interface PubApiRequestComponent { +public interface PubApiRequestComponent { CheckApiAction checkApiAction(); RdapAutnumAction rdapAutnumAction(); RdapDomainAction rdapDomainAction(); diff --git a/core/src/main/java/google/registry/module/tools/ToolsRequestComponent.java b/core/src/main/java/google/registry/module/tools/ToolsRequestComponent.java index e57dfb1fd5c..422b1e75c78 100644 --- a/core/src/main/java/google/registry/module/tools/ToolsRequestComponent.java +++ b/core/src/main/java/google/registry/module/tools/ToolsRequestComponent.java @@ -49,7 +49,7 @@ ToolsServerModule.class, WhiteboxModule.class, }) -interface ToolsRequestComponent { +public interface ToolsRequestComponent { CreateGroupsAction createGroupsAction(); EppToolAction eppToolAction(); FlowComponent.Builder flowComponentBuilder(); diff --git a/core/src/test/java/google/registry/module/RequestComponentTest.java b/core/src/test/java/google/registry/module/RequestComponentTest.java new file mode 100644 index 00000000000..89d313dec9d --- /dev/null +++ b/core/src/test/java/google/registry/module/RequestComponentTest.java @@ -0,0 +1,92 @@ +// Copyright 2024 The Nomulus Authors. All Rights Reserved. +// +// 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 google.registry.module; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableList; +import google.registry.module.backend.BackendRequestComponent; +import google.registry.module.bsa.BsaRequestComponent; +import google.registry.module.frontend.FrontendRequestComponent; +import google.registry.module.pubapi.PubApiRequestComponent; +import google.registry.module.tools.ToolsRequestComponent; +import google.registry.testing.GoldenFileTestHelper; +import google.registry.testing.TestDataHelper; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.testcontainers.shaded.com.google.common.collect.ImmutableMap; + +/** Unit tests for {@link RequestComponent}. */ +public class RequestComponentTest { + private static final ImmutableMap, String> GaeComponents = + ImmutableMap.of( + FrontendRequestComponent.class, "frontend", + BackendRequestComponent.class, "backend", + ToolsRequestComponent.class, "tools", + PubApiRequestComponent.class, "pubapi", + BsaRequestComponent.class, "bsa"); + + @Test + void testRoutingMap() { + GoldenFileTestHelper.assertThatRoutesFromComponent(RequestComponent.class) + .describedAs("routing map") + .isEqualToGolden(RequestComponentTest.class, "routing.txt"); + } + + @Test + void testGaeToJettyRoutingCoverage() { + List jettyRoutes = getRoutes(RequestComponent.class, "routing.txt"); + List gaeRoutes = new ArrayList<>(); + for (var component : GaeComponents.entrySet()) { + gaeRoutes.addAll(getRoutes(component.getKey(), component.getValue() + "_routing.txt")); + } + assertThat(jettyRoutes).containsExactlyElementsIn(gaeRoutes); + } + + private List getRoutes(Class context, String filename) { + return TestDataHelper.loadFile(context, filename) + .trim() + .lines() + .skip(1) // Skip the headers + .map(Route::create) + .toList(); + } + + private record Route( + String path, + String clazz, + String methods, + String ok, + String authMethods, + String min, + String userPolicy) { + private static final Splitter splitter = Splitter.on(' ').omitEmptyStrings().trimResults(); + + static Route create(String line) { + ImmutableList parts = ImmutableList.copyOf(splitter.split(line)); + assertThat(parts.size()).isEqualTo(7); + return new Route( + parts.get(0), + parts.get(1), + parts.get(2), + parts.get(3), + parts.get(4), + parts.get(5), + parts.get(6)); + } + } +} diff --git a/core/src/test/java/google/registry/testing/TestDataHelper.java b/core/src/test/java/google/registry/testing/TestDataHelper.java index c371844edfd..abc93ce38c8 100644 --- a/core/src/test/java/google/registry/testing/TestDataHelper.java +++ b/core/src/test/java/google/registry/testing/TestDataHelper.java @@ -73,13 +73,12 @@ public static ImmutableMap updateSubstitutions( } /** - * Loads a text file from the "testdata" directory relative to the location of the specified - * context class. + * Loads a text file from a directory with a relative path to the location of the specified + * context class under {@code src/test/resources/}. */ public static String loadFile(Class context, String filename) { return fileCache.computeIfAbsent( - FileKey.create(context, filename), - k -> readResourceUtf8(context, filename)); + FileKey.create(context, filename), k -> readResourceUtf8(context, filename)); } /** @@ -101,8 +100,7 @@ public static String loadFile( */ public static ByteSource loadBytes(Class context, String filename) { return byteCache.computeIfAbsent( - FileKey.create(context, filename), - k -> readResourceBytes(context, filename)); + FileKey.create(context, filename), k -> readResourceBytes(context, filename)); } /** diff --git a/core/src/test/resources/google/registry/module/routing.txt b/core/src/test/resources/google/registry/module/routing.txt new file mode 100644 index 00000000000..cd0ad6e8e19 --- /dev/null +++ b/core/src/test/resources/google/registry/module/routing.txt @@ -0,0 +1,82 @@ +PATH CLASS METHODS OK AUTH_METHODS MIN USER_POLICY +/_dr/admin/createGroups CreateGroupsAction POST n API APP ADMIN +/_dr/admin/list/domains ListDomainsAction GET,POST n API APP ADMIN +/_dr/admin/list/hosts ListHostsAction GET,POST n API APP ADMIN +/_dr/admin/list/premiumLists ListPremiumListsAction GET,POST n API APP ADMIN +/_dr/admin/list/registrars ListRegistrarsAction GET,POST n API APP ADMIN +/_dr/admin/list/reservedLists ListReservedListsAction GET,POST n API APP ADMIN +/_dr/admin/list/tlds ListTldsAction GET,POST n API APP ADMIN +/_dr/admin/verifyOte VerifyOteAction POST n API APP ADMIN +/_dr/cron/fanout TldFanoutAction GET y API APP ADMIN +/_dr/dnsRefresh RefreshDnsAction GET y API APP ADMIN +/_dr/epp EppTlsAction POST n API APP ADMIN +/_dr/epptool EppToolAction POST n API APP ADMIN +/_dr/loadtest LoadTestAction POST y API APP ADMIN +/_dr/task/brdaCopy BrdaCopyAction POST y API APP ADMIN +/_dr/task/bsaDownload BsaDownloadAction GET,POST n API APP ADMIN +/_dr/task/bsaRefresh BsaRefreshAction GET,POST n API APP ADMIN +/_dr/task/bsaValidate BsaValidateAction GET,POST n API APP ADMIN +/_dr/task/copyDetailReports CopyDetailReportsAction POST n API APP ADMIN +/_dr/task/deleteExpiredDomains DeleteExpiredDomainsAction GET n API APP ADMIN +/_dr/task/deleteLoadTestData DeleteLoadTestDataAction POST n API APP ADMIN +/_dr/task/deleteProberData DeleteProberDataAction POST n API APP ADMIN +/_dr/task/executeCannedScript CannedScriptExecutionAction POST,GET y API APP ADMIN +/_dr/task/expandBillingRecurrences ExpandBillingRecurrencesAction GET n API APP ADMIN +/_dr/task/exportDomainLists ExportDomainListsAction POST n API APP ADMIN +/_dr/task/exportPremiumTerms ExportPremiumTermsAction POST n API APP ADMIN +/_dr/task/exportReservedTerms ExportReservedTermsAction POST n API APP ADMIN +/_dr/task/generateInvoices GenerateInvoicesAction POST n API APP ADMIN +/_dr/task/generateSpec11 GenerateSpec11ReportAction POST n API APP ADMIN +/_dr/task/generateZoneFiles GenerateZoneFilesAction POST n API APP ADMIN +/_dr/task/icannReportingStaging IcannReportingStagingAction POST n API APP ADMIN +/_dr/task/icannReportingUpload IcannReportingUploadAction POST n API APP ADMIN +/_dr/task/nordnUpload NordnUploadAction POST y API APP ADMIN +/_dr/task/nordnVerify NordnVerifyAction POST y API APP ADMIN +/_dr/task/publishDnsUpdates PublishDnsUpdatesAction POST y API APP ADMIN +/_dr/task/publishInvoices PublishInvoicesAction POST n API APP ADMIN +/_dr/task/publishSpec11 PublishSpec11ReportAction POST n API APP ADMIN +/_dr/task/rdeReport RdeReportAction POST n API APP ADMIN +/_dr/task/rdeStaging RdeStagingAction GET,POST n API APP ADMIN +/_dr/task/rdeUpload RdeUploadAction POST n API APP ADMIN +/_dr/task/readDnsRefreshRequests ReadDnsRefreshRequestsAction POST y API APP ADMIN +/_dr/task/refreshDnsForAllDomains RefreshDnsForAllDomainsAction GET n API APP ADMIN +/_dr/task/refreshDnsOnHostRename RefreshDnsOnHostRenameAction POST n API APP ADMIN +/_dr/task/relockDomain RelockDomainAction POST y API APP ADMIN +/_dr/task/resaveAllEppResourcesPipeline ResaveAllEppResourcesPipelineAction GET n API APP ADMIN +/_dr/task/resaveEntity ResaveEntityAction POST n API APP ADMIN +/_dr/task/sendExpiringCertificateNotificationEmail SendExpiringCertificateNotificationEmailAction GET n API APP ADMIN +/_dr/task/syncGroupMembers SyncGroupMembersAction POST n API APP ADMIN +/_dr/task/syncRegistrarsSheet SyncRegistrarsSheetAction POST n API APP ADMIN +/_dr/task/tmchCrl TmchCrlAction POST y API APP ADMIN +/_dr/task/tmchDnl TmchDnlAction POST y API APP ADMIN +/_dr/task/tmchSmdrl TmchSmdrlAction POST y API APP ADMIN +/_dr/task/updateRegistrarRdapBaseUrls UpdateRegistrarRdapBaseUrlsAction GET y API APP ADMIN +/_dr/task/uploadBsaUnavailableNames UploadBsaUnavailableDomainsAction GET,POST n API APP ADMIN +/_dr/task/wipeOutContactHistoryPii WipeOutContactHistoryPiiAction GET n API APP ADMIN +/_dr/whois WhoisAction POST n API APP ADMIN +/check CheckApiAction GET n API NONE PUBLIC +/console-api/domain ConsoleDomainGetAction GET n API,LEGACY USER PUBLIC +/console-api/domain-list ConsoleDomainListAction GET n API,LEGACY USER PUBLIC +/console-api/registrars RegistrarsAction GET,POST n API,LEGACY USER PUBLIC +/console-api/settings/contacts ContactAction GET,POST n API,LEGACY USER PUBLIC +/console-api/settings/security SecurityAction POST n API,LEGACY USER PUBLIC +/console-api/settings/whois-fields WhoisRegistrarFieldsAction POST n API,LEGACY USER PUBLIC +/console-api/userdata ConsoleUserDataAction GET n API,LEGACY USER PUBLIC +/rdap/autnum/(*) RdapAutnumAction GET,HEAD n API NONE PUBLIC +/rdap/domain/(*) RdapDomainAction GET,HEAD n API NONE PUBLIC +/rdap/domains RdapDomainSearchAction GET,HEAD n API NONE PUBLIC +/rdap/entities RdapEntitySearchAction GET,HEAD n API NONE PUBLIC +/rdap/entity/(*) RdapEntityAction GET,HEAD n API NONE PUBLIC +/rdap/help(*) RdapHelpAction GET,HEAD n API NONE PUBLIC +/rdap/ip/(*) RdapIpAction GET,HEAD n API NONE PUBLIC +/rdap/nameserver/(*) RdapNameserverAction GET,HEAD n API NONE PUBLIC +/rdap/nameservers RdapNameserverSearchAction GET,HEAD n API NONE PUBLIC +/registrar ConsoleUiAction GET n API,LEGACY NONE PUBLIC +/registrar-create ConsoleRegistrarCreatorAction POST,GET n API,LEGACY NONE PUBLIC +/registrar-ote-setup ConsoleOteSetupAction POST,GET n API,LEGACY NONE PUBLIC +/registrar-ote-status OteStatusAction POST n API,LEGACY USER PUBLIC +/registrar-settings RegistrarSettingsAction POST n API,LEGACY USER PUBLIC +/registry-lock-get RegistryLockGetAction GET n API,LEGACY USER PUBLIC +/registry-lock-post RegistryLockPostAction POST n API,LEGACY USER PUBLIC +/registry-lock-verify RegistryLockVerifyAction GET n API,LEGACY NONE PUBLIC +/whois/(*) WhoisHttpAction GET n API NONE PUBLIC