-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(server): load plateau spec info from cms dynamically #345
Conversation
WalkthroughThe changes in this pull request involve several modifications across multiple files in the Changes
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 15
🧹 Outside diff range and nitpick comments (20)
server/datacatalog/datacatalogv3/spec.go (1)
10-25
: LGTM: Well-implemented function with proper error handling and filtering.The
getPlateauSpecs
function is correctly implemented with appropriate error handling, efficient slice pre-allocation, and correct filtering logic. It effectively converts the filtered specs to the simplified version usingtoSimpleSpec
.Consider adding a check for negative
maxYear
values, as they might lead to unexpected behavior:func getPlateauSpecs(ctx context.Context, pcms plateaucms.SpecStore, maxYear int) ([]plateauapi.PlateauSpecSimple, error) { + if maxYear < 0 { + return nil, fmt.Errorf("maxYear must be non-negative") + } res, err := pcms.PlateauSpecs(ctx) if err != nil { return nil, err } // ... rest of the function }server/plateaucms/context.go (2)
9-12
: LGTM: Context key types are well-defined.The use of empty structs as context keys is a good practice. The naming is consistent and descriptive.
Consider adding a brief comment above each type to explain its purpose, for improved code readability. For example:
// plateauCMSContextKey is used to store and retrieve the Plateau CMS instance from context type plateauCMSContextKey struct{}
14-21
: LGTM: GetPlateauCMSFromContext and SetPlateauCMSToContext are well-implemented.Both functions correctly use the
plateauCMSContextKey
and follow Go conventions.In
GetPlateauCMSFromContext
, consider adding a nil check to make the function more robust:func GetPlateauCMSFromContext(ctx context.Context) *CMS { if ctx == nil { return nil } cms, _ := ctx.Value(plateauCMSContextKey{}).(*CMS) return cms }server/cmsintegration/cmsintegrationcommon/config.go (1)
Line range hint
1-48
: Overall, the changes look good and align with the PR objectives.The modifications to the
Config
struct, including the addition of theCMSSystemProject
field and the reformatting of existing CMS-related fields, are consistent with the PR's goal of loading plateau spec info from CMS dynamically. These changes should enhance the flexibility and functionality of the CMS integration.As the CMS-related configuration grows, consider grouping these fields into a separate struct within the
Config
struct for better organization and maintainability. For example:type CMSConfig struct { BaseURL string Token string Integration string SystemProject string } type Config struct { // ...other fields CMS CMSConfig // ...remaining fields }This structure would make it easier to manage CMS-specific configurations and potentially simplify future additions or modifications to CMS-related settings.
server/datacatalog/datacatalogv3/cms_test.go (2)
34-38
: LGTM: Proper initialization of plateaucms client.The initialization of the plateaucms client is well-implemented, using environment variables for sensitive information. The error handling is correct.
Consider adding a more descriptive error message when asserting no error:
-assert.NoError(t, err) +assert.NoError(t, err, "Failed to initialize plateaucms client")This will provide more context if the test fails due to client initialization issues.
Line range hint
1-70
: Summary: Changes align with PR objectives and enhance CMS integration.The modifications in this test file successfully incorporate the new plateaucms client, aligning with the PR objective of loading plateau spec info from CMS dynamically. The changes are well-implemented, with proper error handling and use of environment variables for sensitive information.
Key points:
- New plateaucms package is correctly imported and utilized.
- Plateaucms client is properly initialized with correct configuration.
- NewCMS function call is updated to include the new plateaucms client.
These changes contribute to the goal of dynamically loading plateau spec info from CMS, improving the flexibility and maintainability of the system.
As the system evolves to use dynamic CMS loading, consider the following:
- Ensure consistent error handling and logging throughout the codebase for CMS-related operations.
- Document the new CMS integration process for other developers.
- Consider adding integration tests to verify the end-to-end functionality of the dynamic CMS loading process.
server/datacatalog/datacatalogv3/repos.go (1)
34-34
: Consider using a more descriptive field nameThe addition of the
pcms
field of typeplateaucms.SpecStore
is consistent with the new import and changes in theNewRepos
function. However, consider using a more descriptive name for this field to improve code readability. For example,plateauSpecStore
orplateauCMSStore
might be more explicit.server/plateaucms/plateau-spec_test.go (3)
15-31
: LGTM! Well-structured test function with good coverage.The
TestMinorVersionsFromMax
function provides good coverage for theminorVersionsFromMax
function, testing multiple scenarios including edge cases. The test cases are clear and easy to understand.To improve readability, consider adding a brief comment before each test case to describe the scenario being tested. For example:
// Test case: Multiple minor versions assert.Equal( t, []string{"3.0", "3.1", "3.2", "3.3", "3.4", "3.5"}, minorVersionsFromMax(3, 5), )This would make it easier for other developers to understand the purpose of each test case at a glance.
33-64
: Good test setup, but consider improving error handling and coverage.The
TestCMS_PlateauSpecs
function provides a good test for the happy path of thePlateauSpecs
method. The use ofhttpmock
for mocking HTTP responses is appropriate.However, there are a few areas for improvement:
Error handling: The use of
lo.Must
in the CMS initialization (line 41) will panic if an error occurs. Consider handling this error explicitly to make the test more robust.Test coverage: The test only covers the successful scenario. Consider adding test cases for error scenarios, such as:
- HTTP request failure
- Invalid JSON response
- Empty response
Assertions: While the current assertions check for no error and correct output, you might want to add assertions to verify that the mock was actually called.
Here's an example of how you could improve the error handling:
cmsMain, err := cms.New(testCMSHost, testCMSToken) assert.NoError(t, err) cms := &CMS{ cmsbase: testCMSHost, cmsMetadataProject: tokenProject, cmsMain: cmsMain, }
66-98
: LGTM! Well-structured mock function with realistic test data.The
mockCMSPlateauSpec
function provides a comprehensive mock setup for the CMS HTTP responses. The use of realistic test data is commendable and will help ensure the tests are meaningful.One minor suggestion for improvement:
Replace the use of
lo.Must
in the URL construction with explicit error handling. This will make the test more robust and prevent potential panics. For example:url, err := url.JoinPath(testCMSHost, "api", "projects", tokenProject, "models", plateauSpecModel, "items") assert.NoError(t, err) httpmock.RegisterResponder( "GET", url, // ... rest of the code )This change will make the test more resilient to unexpected errors and provide clearer feedback if something goes wrong during URL construction.
server/cmsintegration/cmsintegrationv3/fme.go (1)
130-133
: LGTM! Consider adding a constructor functionThe
fmeMock
struct is well-designed for use in unit tests. It allows tracking of requests and simulating error conditions.Consider adding a constructor function to initialize the
fmeMock
struct. This would ensure consistent initialization and potentially allow for future expansion without changing all instantiation sites. For example:func newFMEMock() *fmeMock { return &fmeMock{ called: make([]fmeRequest, 0), } }server/datacatalog/datacatalogv3/repos_test.go (2)
24-30
: LGTM with suggestions: New plateaucms client creation and usageThe addition of the
pcms
client and its usage inNewRepos()
is consistent with the described changes. However, consider the following suggestions:
Instead of hardcoding the configuration parameters, consider using environment variables or test constants. This would make the tests more flexible and easier to maintain.
Ensure that the
NewRepos()
function's signature change (to accept thepcms
client) is properly implemented and documented in the main code.Would you like me to provide an example of how to use environment variables for the configuration?
165-193
: LGTM with a minor suggestion: New mock responder for plateau-spec itemsThe addition of the new mock responder for plateau-spec items is well-implemented and consistent with the described changes. It provides good test coverage for different plateau spec versions.
Suggestion for improved readability:
Consider extracting the mock data into a separate variable or constant. This would make the code more readable and easier to maintain, especially if the mock data needs to be updated in the future.Would you like an example of how to extract the mock data into a separate variable?
server/config.go (1)
135-135
: Consider clarifying the naming and usage of CMS project fields.The new field
CMSSystemProject
is being assigned the value ofc.CMS_TokenProject
. However, there's already aCMSTokenProject
field (line 136) that also usesc.CMS_TokenProject
. This could lead to confusion about the purpose and difference between these two fields.Consider the following:
- If these fields serve different purposes, consider using distinct values or clarifying the naming to reflect their specific roles.
- If they are meant to be the same, consider using only one field to avoid duplication.
Could you provide more context on the intended difference between
CMSSystemProject
andCMSTokenProject
?server/cmsintegration/cmsintegrationv3/model.go (1)
139-151
: LGTM! Consider adding input validation and error logging.The
SpecMajorVersionInt()
method is a valuable addition to theCityItem
struct, providing functionality to extract the major version number from theSpec
field. The implementation correctly handles potential errors and edge cases.Consider the following improvements:
- Add input validation for the
Spec
field format before processing. This could help catch unexpected formats early.- Consider logging errors when the conversion fails or when the
Spec
format is invalid. This could aid in debugging and monitoring.Here's a suggested implementation incorporating these improvements:
func (i *CityItem) SpecMajorVersionInt() int { + if !strings.Contains(i.Spec, ".") { + log.Printf("Invalid Spec format: %s", i.Spec) + return 0 + } + m, _, ok := strings.Cut(i.Spec, ".") if !ok { + log.Printf("Failed to split Spec: %s", i.Spec) return 0 } v, err := strconv.Atoi(m) if err != nil { + log.Printf("Failed to convert major version to int: %v", err) return 0 } return v }These changes would improve the robustness and debuggability of the method.
server/cmsintegration/cmsintegrationv3/service_fme_test.go (1)
23-35
: Consider expanding test coverage for PlateauCMS integrationWhile the
plateauCMSMock
is well-implemented, consider adding more test cases to cover various scenarios with PlateauCMS integration. This could include:
- Testing with different
PlateauSpec
configurations.- Verifying error handling when
PlateauSpecs
returns an error.- Checking how the system behaves with empty
PlateauSpecs
results.These additional test cases would ensure more robust coverage of the PlateauCMS integration.
server/plateaucms/plateau-spec.go (1)
18-24
: Add Validation toPlateauSpec
Struct FieldsTo ensure data integrity, consider adding validation for the
PlateauSpec
fields, such as checking for negative numbers or zero values where they are not meaningful.Optionally, implement a
Validate
method:func (s PlateauSpec) Validate() error { if s.ID == "" { return fmt.Errorf("ID is required") } if s.MajorVersion < 0 { return fmt.Errorf("MajorVersion cannot be negative") } if s.MaxMinorVersion < 0 { return fmt.Errorf("MaxMinorVersion cannot be negative") } if s.Year <= 0 { return fmt.Errorf("Year must be a positive number") } return nil }server/cmsintegration/cmsintegrationv3/service.go (1)
29-34
: Consider enhancing clarity by renaming thePCMS
fieldThe
Services
struct now includes thePCMS
field of typeplateaucms.SpecStore
. To improve code readability and avoid potential confusion with the existingCMS
field, consider renamingPCMS
to something more descriptive likePlateauCMS
orSpecStore
.If applicable, apply this refactor:
type Services struct { CMS cms.Interface HTTP *http.Client TaskRunner gcptaskrunner.TaskRunner - PCMS plateaucms.SpecStore + PlateauCMS plateaucms.SpecStore FMEResultURL string mockFME fmeInterface }server/datacatalog/datacatalogv3/cms.go (1)
Line range hint
28-37
: RefactorNewCMS
constructor to reduce parameter countThe
NewCMS
function now has seven parameters, which can make it difficult to maintain and increases the risk of parameter misordering during calls. Consider refactoring the constructor to use a configuration struct to improve readability and maintainability.Here's an example using a configuration struct:
type CMSConfig struct { CMS cms.Interface PCMS plateaucms.SpecStore Year int Plateau bool Project string Cache bool } func NewCMS(config CMSConfig) *CMS { return &CMS{ cms: config.CMS, pcms: config.PCMS, year: config.Year, plateau: config.Plateau, cache: config.Cache, cacheDir: filepath.Join(cacheDir, cachePrefix+config.Project), } }server/cmsintegration/cmsintegrationv3/service_fme.go (1)
113-119
: Ensure consistent language in error messagesThe error message returned by
fmt.Errorf("fme url is not set")
is in English, whereas the message passed tofailToConvert()
is in Japanese ("FMEのURLが設定されていません。"). For consistency and clarity, consider using the same language for both messages.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (20)
- server/cmsintegration/cmsintegrationcommon/config.go (1 hunks)
- server/cmsintegration/cmsintegrationv3/fme.go (2 hunks)
- server/cmsintegration/cmsintegrationv3/fme_test.go (0 hunks)
- server/cmsintegration/cmsintegrationv3/model.go (3 hunks)
- server/cmsintegration/cmsintegrationv3/service.go (5 hunks)
- server/cmsintegration/cmsintegrationv3/service_fme.go (1 hunks)
- server/cmsintegration/cmsintegrationv3/service_fme_test.go (3 hunks)
- server/config.go (1 hunks)
- server/datacatalog/datacatalogv3/cms.go (3 hunks)
- server/datacatalog/datacatalogv3/cms_test.go (2 hunks)
- server/datacatalog/datacatalogv3/consts.go (0 hunks)
- server/datacatalog/datacatalogv3/repos.go (3 hunks)
- server/datacatalog/datacatalogv3/repos_test.go (4 hunks)
- server/datacatalog/datacatalogv3/spec.go (1 hunks)
- server/datacatalog/repos.go (1 hunks)
- server/plateaucms/cms.go (3 hunks)
- server/plateaucms/context.go (1 hunks)
- server/plateaucms/metadata.go (1 hunks)
- server/plateaucms/plateau-spec.go (1 hunks)
- server/plateaucms/plateau-spec_test.go (1 hunks)
💤 Files with no reviewable changes (2)
- server/cmsintegration/cmsintegrationv3/fme_test.go
- server/datacatalog/datacatalogv3/consts.go
🧰 Additional context used
🔇 Additional comments (25)
server/datacatalog/datacatalogv3/spec.go (2)
1-8
: LGTM: Package structure and imports are appropriate.The package name
datacatalogv3
is suitable for the functionality provided. The imports are relevant to the implemented functions, and there are no unused imports.
27-33
: LGTM: Concise and focused conversion function.The
toSimpleSpec
function efficiently converts aPlateauSpec
to aPlateauSpecSimple
. It correctly maps the required fields and uses theMinorVersions()
method to retrieve the minor versions.server/plateaucms/context.go (4)
1-7
: LGTM: Package declaration and imports are appropriate.The package name
plateaucms
aligns with the file's location, and the import of the CMS package is relevant for the functionality provided in this file.
1-36
: Overall assessment: Well-implemented context management for Plateau CMS.This new file introduces a set of utility functions for managing Plateau CMS data using Go's context package. The implementation is consistent, follows Go best practices, and provides a clean API for context-based data management.
Key points:
- Appropriate use of empty structs as context keys.
- Consistent implementation of getter and setter functions.
- Clear separation of concerns for different types of CMS data.
The suggestions provided in the review comments, such as adding comments to type definitions and including nil checks, will further improve the code quality. Additionally, clarifying the relationships between different CMS-related types (
*CMS
,cms.Interface
,Metadata
,MetadataList
) will enhance the overall understanding of the package's architecture.
28-36
: LGTM: GetCMSMetadataFromContext and GetAllCMSMetadataFromContext are well-implemented.Both functions correctly use their respective context keys and follow the established pattern.
Could you provide more information about the
Metadata
andMetadataList
types? They're not defined in this file, so it would be helpful to understand their structure and purpose.To help verify the usage and definition of these types, please run the following script:
#!/bin/bash # Description: Check the definition and usage of Metadata and MetadataList types echo "Definition of Metadata type:" rg --type go "type Metadata struct" -g '!context.go' echo "\nDefinition of MetadataList type:" rg --type go "type MetadataList" -g '!context.go' echo "\nUsage of Metadata type:" rg --type go "Metadata" -g '!context.go' echo "\nUsage of MetadataList type:" rg --type go "MetadataList" -g '!context.go'
23-26
: LGTM: GetCMSFromContext is well-implemented, but clarification needed.The function correctly uses the
cmsContextKey
and follows the established pattern.Could you clarify the relationship between
*CMS
andcms.Interface
? It seems that different types are being used for similar purposes in the context. Is this intentional, and if so, what's the reasoning behind it?To help verify the usage of these types, please run the following script:
✅ Verification successful
Action Required: Correct and Rerun the Shell Script.
The previous shell script did not provide information on
*CMS
andcms.Interface
usages, likely due to a formatting issue. Please use the corrected script below to gather the necessary details:
LGTM: Consistent use of
*CMS
andcms.Interface
confirmed.The function appropriately returns
cms.Interface
, aligning with the existing codebase patterns where*CMS
implementscms.Interface
. This design allows for flexibility and easier testing.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check the usage of CMS and cms.Interface types in the codebase # Search for CMS type usage echo "Usage of *CMS type:" rg --type go "\\*CMS" -g '!context.go' echo "\nUsage of cms.Interface type:" rg --type go "cms\\.Interface" -g '!context.go'Length of output: 18013
Script:
#!/bin/bash # Description: Check the usage of CMS and cms.Interface types in the codebase # Search for CMS type usage echo "Usage of *CMS type:" rg --type go "\\*CMS" -g '!context.go' echo "\nUsage of cms.Interface type:" rg --type go "cms\\.Interface" -g '!context.go'Length of output: 11271
server/cmsintegration/cmsintegrationcommon/config.go (1)
10-13
: LGTM! Consider documenting the newCMSSystemProject
field.The reformatting of the existing CMS-related fields improves code readability and consistency. The addition of the
CMSSystemProject
field suggests an expansion of CMS-related functionality.Consider adding a comment to explain the purpose and usage of the new
CMSSystemProject
field, similar to the comments provided for other sections of theConfig
struct.To confirm the removal of the
FMEURLV3
field mentioned in the AI summary, let's run the following script:✅ Verification successful
FMEURLV3 Field Successfully Removed
The
FMEURLV3
field has been confirmed to be removed from theConfig
struct, and there are no remaining usages in the codebase.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the removal of FMEURLV3 field and its usages # Test 1: Check if FMEURLV3 field still exists in the Config struct echo "Test 1: Checking for FMEURLV3 field in Config struct" rg --type go "FMEURLV3\s+string" server/cmsintegration/cmsintegrationcommon/config.go # Test 2: Search for any remaining usages of FMEURLV3 in the codebase echo "Test 2: Searching for FMEURLV3 usages in the codebase" rg --type go "FMEURLV3" echo "If no results are shown above, it confirms that FMEURLV3 has been completely removed."Length of output: 524
server/datacatalog/datacatalogv3/cms_test.go (1)
9-9
: LGTM: New import for plateaucms package.The addition of the plateaucms package import is correct and necessary for the changes made in the test function.
server/datacatalog/datacatalogv3/repos.go (3)
10-10
: LGTM: New import added for plateaucms packageThe addition of the
plateaucms
package import is consistent with the changes made to theRepos
struct and its methods. This import is necessary for the new functionality being introduced.
40-43
: LGTM: NewRepos function updated correctlyThe changes to the
NewRepos
function are consistent with the newpcms
field in theRepos
struct. The function now correctly initializes thepcms
field with the passed parameter, while preserving the initialization of thecms
field. This update maintains existing functionality while incorporating the newplateaucms.SpecStore
dependency.
94-94
: LGTM: setCMS method updated, verify NewCMS functionThe update to the
setCMS
method, passingr.pcms
to theNewCMS
function, is consistent with the changes made to theRepos
struct. This change appears to be correct, assuming theNewCMS
function has been updated elsewhere to accept this new parameter.To ensure consistency, please verify that the
NewCMS
function signature has been updated accordingly in its definition. Run the following script to check theNewCMS
function signature:✅ Verification successful
Verified: NewCMS function signature matches usage
The
NewCMS
function inserver/datacatalog/datacatalogv3/cms.go
correctly accepts the parameters used inserver/datacatalog/datacatalogv3/repos.go
at line 94. The update to thesetCMS
method is consistent and accurate.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the NewCMS function signature # Test: Search for the NewCMS function definition rg --type go -A 5 'func NewCMS\('Length of output: 901
server/plateaucms/plateau-spec_test.go (2)
3-13
: LGTM! Import statements are appropriate.The import statements are well-organized and include all necessary packages for the test file. The use of
httpmock
for mocking HTTP responses is a good practice for testing HTTP clients.Note: The
lo
package is used for utility functions. While this is fine, ensure that its usage doesn't overcomplicate the code or introduce unnecessary dependencies.
1-98
: Overall, well-structured and comprehensive test file.This test file for the
plateaucms
package is well-organized and provides good coverage for thePlateauSpecs
functionality. The use ofhttpmock
for mocking HTTP responses is appropriate, and the test data is realistic.Main points for improvement:
- Add comments to describe individual test cases in
TestMinorVersionsFromMax
for better readability.- Improve error handling in
TestCMS_PlateauSpecs
, especially when initializing the CMS struct.- Expand test coverage in
TestCMS_PlateauSpecs
to include error scenarios.- Replace
lo.Must
usage with explicit error handling inmockCMSPlateauSpec
.Addressing these points will further enhance the robustness and clarity of the tests.
server/datacatalog/datacatalogv3/repos_test.go (2)
10-10
: LGTM: Import statement added for plateaucms packageThe addition of the
plateaucms
import is consistent with the changes described in the summary and is necessary for the new functionality being introduced in this test file.
Line range hint
1-324
: Overall assessment: Well-implemented changes with minor suggestionsThe changes in this file successfully integrate the new
plateaucms
functionality into the test suite. The additions include:
- A new import for the
plateaucms
package.- Creation and usage of a
plateaucms
client in theTestRepos
function.- A new mock responder for plateau-spec items.
These changes improve the test coverage for the new plateau-spec functionality and are consistent with the described objectives of the pull request.
Minor suggestions were made to:
- Use environment variables or test constants for the
plateaucms
client configuration.- Extract the mock data for plateau-spec items into a separate variable for improved readability.
Overall, the changes look good and achieve the intended goals. After addressing the minor suggestions, this file should be ready for merging.
server/cmsintegration/cmsintegrationv3/model.go (1)
95-110
: LGTM! Verify usage of renamed field across the codebase.The renaming of
SpecificationVersion
toSpec
in theCityItem
struct simplifies the field name while maintaining its purpose. This change is consistent with the provided summary.To ensure that this change doesn't introduce any issues, please run the following script to verify the usage of the renamed field across the codebase:
This will help identify any places where the old field name might still be in use and confirm the correct usage of the new field name.
✅ Verification successful
Verified: The
SpecificationVersion
field has been successfully removed and replaced bySpec
across the codebase. No residual usages ofSpecificationVersion
were found.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for any remaining usage of 'SpecificationVersion' and new usage of 'Spec' echo "Checking for any remaining usage of 'SpecificationVersion':" rg --type go 'SpecificationVersion' echo "Checking for new usage of 'Spec':" rg --type go 'Spec'Length of output: 76281
server/cmsintegration/cmsintegrationv3/service_fme_test.go (2)
1023-1026
: LGTM: New mock structure for PlateauCMSThe
plateauCMSMock
structure is well-defined and implements theplateaucms.SpecStore
interface. It includes a function fieldplateauSpecs
which allows for flexible mocking of thePlateauSpecs
method.
1028-1030
: LGTM: PlateauSpecs method implementationThe
PlateauSpecs
method is correctly implemented, delegating to theplateauSpecs
function field. This allows for easy customization of the mock behavior in tests.server/plateaucms/cms.go (1)
175-177
: Verify the definition ofplateauCMSContextKey{}
to avoid context key collisionsEnsure that the context key
plateauCMSContextKey{}
is defined as an unexported type to prevent potential collisions with other context keys. This is a best practice in Go when using context values.Run the following script to verify the context key definition:
✅ Verification successful
Context key
plateauCMSContextKey{}
is properly defined as an unexported typeThe context key
plateauCMSContextKey{}
is correctly defined as an unexported type inserver/plateaucms/context.go:9
. This adheres to best practices, effectively preventing potential context key collisions.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Search for the definition of plateauCMSContextKey # Expected result: The context key should be defined as a unique unexported type. rg --type go --no-heading --line-number 'type plateauCMSContextKey struct{}'Length of output: 228
Script:
#!/bin/bash # Description: Search for the definition of plateauCMSContextKey with escaped braces # Expected result: The context key should be defined as a unique unexported type. rg --type go --no-heading --line-number 'type plateauCMSContextKey struct\{\}'Length of output: 146
server/cmsintegration/cmsintegrationv3/service.go (3)
15-15
: Importingplateaucms
package forSpecStore
usage is appropriateThe addition of the
plateaucms
import is necessary for utilizing theSpecStore
interface in theServices
struct.
57-65
: Initialization ofPlateauCMS
is properly handledThe
PCMS
field is correctly initialized with theplateaucms.New
function, and error handling is appropriately implemented to handle any initialization failures.
93-98
:GetFME
method correctly returns the appropriate FME interfaceThe
GetFME
method provides the correct FME interface based on whethermockFME
is set. It returns themockFME
instance when available or creates a new FME instance usings.FMEResultURL
.server/datacatalog/datacatalogv3/cms.go (1)
Line range hint
47-51
: EnsuregetPlateauSpecs
handles context and errors appropriatelyThe integration of
getPlateauSpecs
within theGetAll
method appears correct. Please verify that thegetPlateauSpecs
function is properly defined, handles context cancellation, and propagates errors correctly to prevent potential issues during data retrieval.server/cmsintegration/cmsintegrationv3/service_fme.go (1)
113-119
: Verify all references tos.FME
are updated to usefme
The code introduces a new
fme
variable obtained vias.GetFME()
. To prevent unintended behavior, please ensure that all references tos.FME
within this file are updated to use the newfme
variable.To verify that there are no remaining references to
s.FME
, run the following script:✅ Verification successful
All references to
s.FME
have been successfully updated tofme
inservice_fme.go
.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Search for any remaining references to `s.FME` in the codebase. # Expected result: No matches should be found in `service_fme.go`. rg 's\.FME' server/cmsintegration/cmsintegrationv3/service_fme.goLength of output: 67
server/datacatalog/repos.go (1)
49-49
: Function initialization updated withpcms
parameterInjecting
pcms
intodatacatalogv3.NewRepos
enhances modularity and promotes better dependency management. This change aligns with best practices for dependency injection and improves the testability of your code.Please verify that all other calls to
datacatalogv3.NewRepos
in the codebase have been updated to include thepcms
parameter to prevent any potential runtime errors.Run the following script to check for instances where
datacatalogv3.NewRepos
is called without parameters:
}) | ||
assert.NoError(t, err) | ||
|
||
c2 := NewCMS(c, pcms, 2023, true, "", false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Inconsistent NewCMS
Function Signature Detected
The NewCMS
function has differing signatures across the codebase, which may lead to integration issues. Please review and standardize the function signatures as necessary.
server/sdkapi/sdkapiv2/cms.go
:NewCMS(c cms.Interface, pac *cms.PublicAPIClient[Item], project string, usePublic bool)
server/sdkapi/sdkapiv2/api_test.go
: CallsNewCMS
with four parameters.server/sdkapi/sdkapiv2/api.go
: CallsNewCMS
with four parameters.
🔗 Analysis chain
Verify NewCMS function signature change across the codebase.
The modification to include the pcms
client in the NewCMS
function call is correct and consistent with the earlier changes. However, we should ensure that this change in function signature is applied consistently across the entire codebase.
Let's verify the NewCMS
function usage across the codebase:
Please review the results to ensure all NewCMS
calls have been updated correctly.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify all function calls to NewCMS match the new signature.
# Test: Search for the NewCMS function usage. Expect: Only occurrences of the new signature.
rg --type go -A 5 $'NewCMS\('
Length of output: 2253
func (f *fmeMock) Request(ctx context.Context, r fmeRequest) error { | ||
f.called = append(f.called, r) | ||
d, err := json.Marshal(r) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Printf("fmeMock: %s\n", string(d)) | ||
return f.err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve error handling and logging in Request method
The Request
method implementation is good for mocking purposes, but there are a few areas that could be improved:
- Consider using a logger instead of
fmt.Printf
for better control over output in tests. - Improve error handling by wrapping the JSON marshaling error.
- Consider adding a mutex to make the mock safe for concurrent use.
Here's a suggested implementation:
import (
"sync"
"github.com/reearth/reearthx/log"
)
type fmeMock struct {
mu sync.Mutex
called []fmeRequest
err error
}
func (f *fmeMock) Request(ctx context.Context, r fmeRequest) error {
f.mu.Lock()
defer f.mu.Unlock()
f.called = append(f.called, r)
d, err := json.Marshal(r)
if err != nil {
return fmt.Errorf("failed to marshal request: %w", err)
}
log.Debugf("fmeMock: %s", string(d))
return f.err
}
These changes will make the mock more robust and easier to use in various testing scenarios.
func (f *fmeMock) Called() []fmeRequest { | ||
return f.called | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider adding mutex protection to Called method
The Called
method looks good, but to ensure thread-safety:
Consider adding mutex protection to this method as well:
func (f *fmeMock) Called() []fmeRequest {
f.mu.Lock()
defer f.mu.Unlock()
return append([]fmeRequest{}, f.called...)
}
This ensures that the called
slice is not modified while it's being read, and returns a copy to prevent external modifications.
if url == "" || resultURL == "" { | ||
return nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider returning an error instead of nil
The addition of this check is a good defensive programming practice. However, returning nil
without any context might make it difficult for the caller to understand why the function failed.
Consider modifying the function to return an error, like this:
-func newFME(url, resultURL string) *fme {
+func newFME(url, resultURL string) (*fme, error) {
if url == "" || resultURL == "" {
- return nil
+ return nil, errors.New("url and resultURL must not be empty")
}
return &fme{
url: url,
resultURL: resultURL,
client: http.DefaultClient,
- }
+ }, nil
}
This change would require updating all calls to newFME
to handle the returned error, but it would provide more robust error handling.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if url == "" || resultURL == "" { | |
return nil | |
} | |
if url == "" || resultURL == "" { | |
return nil, errors.New("url and resultURL must not be empty") | |
} |
pc := &plateauCMSMock{ | ||
plateauSpecs: func(ctx context.Context) ([]plateaucms.PlateauSpec, error) { | ||
return []plateaucms.PlateauSpec{ | ||
{ | ||
ID: "1", | ||
MajorVersion: 3, | ||
Year: 2023, | ||
MaxMinorVersion: 5, | ||
FMEURL: "https://example.com/v3", | ||
}, | ||
}, nil | ||
}, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
plateauCMSMock is defined but not utilized in assertions
The plateauCMSMock
is initialized in the test file but is not injected into the Services
struct or used in any assertions. Please update the test cases to ensure that the mock is properly integrated and its interactions are verified.
🔗 Analysis chain
Verify usage of plateauCMSMock in test cases
The plateauCMSMock
is correctly initialized with a sample PlateauSpec
. However, it's not clear from the provided code snippet how this mock is being used in the test cases. Ensure that the test cases are updated to verify the interaction with the PlateauCMS mock.
To confirm the proper usage of the plateauCMSMock
, run the following script:
Further verify the integration and usage of plateauCMSMock
in the test suite
To ensure that the plateauCMSMock
is properly integrated and utilized within the test cases, please run the following scripts:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for usage of plateauCMSMock in test cases
# Test: Search for plateauCMSMock usage in test cases
rg --type go -C 10 "plateauCMSMock" server/cmsintegration/cmsintegrationv3/service_fme_test.go
# Test: Verify if PCMS field is used in assertions
rg --type go -C 5 "assert.*PCMS" server/cmsintegration/cmsintegrationv3/service_fme_test.go
Length of output: 1226
Script:
#!/bin/bash
# Description: Check for injection and usage of plateauCMSMock in test cases
# Search for assignments to the PCMS field with plateauCMSMock
rg --type go 'PCMS\s*=\s*&plateauCMSMock' server/cmsintegration/cmsintegrationv3/service_fme_test.go
# Search for any method calls or interactions with plateauCMSMock
rg --type go 'plateauCMSMock\.' server/cmsintegration/cmsintegrationv3/service_fme_test.go
# Search across the entire codebase for any usage of plateauCMSMock
rg --type go 'plateauCMSMock' --ignore-file .gitignore
Length of output: 575
server/plateaucms/metadata.go
Outdated
} | ||
|
||
md, ok := lo.Find(l, func(i Metadata) bool { | ||
return findDataCatalog && i.DataCatalogProjectAlias == prj || i.ProjectAlias == prj |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarify logical expression with parentheses
The logical expression in the FindMetadata
method may lead to unintended behavior due to operator precedence. To ensure the intended logic is clear, consider adding parentheses.
Apply this diff to clarify the logic:
-return findDataCatalog && i.DataCatalogProjectAlias == prj || i.ProjectAlias == prj
+return (findDataCatalog && i.DataCatalogProjectAlias == prj) || i.ProjectAlias == prj
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
return findDataCatalog && i.DataCatalogProjectAlias == prj || i.ProjectAlias == prj | |
return (findDataCatalog && i.DataCatalogProjectAlias == prj) || i.ProjectAlias == prj |
server/plateaucms/metadata.go
Outdated
DataCatalogSchemaVersion string `json:"datacatalog_schema_version" cms:"datacatalog_schema_version,select"` | ||
CMSAPIKey string `json:"cms_apikey" cms:"cms_apikey,text"` | ||
SidebarAccessToken string `json:"sidebar_access_token" cms:"sidebar_access_token,text"` | ||
SubPorjectAlias string `json:"subproject_alias" cms:"subproject_alias,text"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in field name "SubPorjectAlias"
The field name SubPorjectAlias
in the Metadata
struct appears to have a typographical error. It should be SubProjectAlias
.
Apply this diff to correct the typo:
- SubPorjectAlias string `json:"subproject_alias,text"`
+ SubProjectAlias string `json:"subproject_alias,text"`
Committable suggestion was skipped due to low confidence.
server/plateaucms/metadata.go
Outdated
if err != nil || items == nil { | ||
if errors.Is(err, cms.ErrNotFound) || items == nil { | ||
return nil, rerror.ErrNotFound | ||
} | ||
return nil, rerror.ErrInternalBy(fmt.Errorf("plateaucms: failed to get metadata: %w", err)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle potential nil error when items
is nil
In the AllMetadata
method, if err
is nil
but items
is nil
, the code attempts to wrap a nil
error, which could lead to unexpected behavior.
Consider modifying the error handling to account for a nil
err
:
-if err != nil || items == nil {
- if errors.Is(err, cms.ErrNotFound) || items == nil {
+if err != nil {
+ if errors.Is(err, cms.ErrNotFound) {
return nil, rerror.ErrNotFound
}
return nil, rerror.ErrInternalBy(fmt.Errorf("plateaucms: failed to get metadata: %w", err))
+} else if items == nil {
+ return nil, rerror.ErrInternalBy(errors.New("plateaucms: items is nil"))
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if err != nil || items == nil { | |
if errors.Is(err, cms.ErrNotFound) || items == nil { | |
return nil, rerror.ErrNotFound | |
} | |
return nil, rerror.ErrInternalBy(fmt.Errorf("plateaucms: failed to get metadata: %w", err)) | |
} | |
if err != nil { | |
if errors.Is(err, cms.ErrNotFound) { | |
return nil, rerror.ErrNotFound | |
} | |
return nil, rerror.ErrInternalBy(fmt.Errorf("plateaucms: failed to get metadata: %w", err)) | |
} else if items == nil { | |
return nil, rerror.ErrInternalBy(errors.New("plateaucms: items is nil")) | |
} |
s.FMEResultURL = resultURL | ||
} else { | ||
s.mockFME = &fmeMock{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure consistent use of fmeHandlerPath
for FME result URL
In the NewServices
function, the FMEResultURL
is set using a hardcoded path "/notify_fme"
, whereas there is a constant fmeHandlerPath
defined as "/notify_fme/v3"
. This discrepancy might lead to inconsistencies or errors in the FME result handling.
Apply this diff to use the defined constant for consistency:
if !c.FMEMock {
- resultURL, err := url.JoinPath(c.Host, "/notify_fme")
+ resultURL, err := url.JoinPath(c.Host, fmeHandlerPath)
if err != nil {
return nil, fmt.Errorf("failed to init fme: %w", err)
}
s.FMEResultURL = resultURL
} else {
s.mockFME = &fmeMock{}
}
Committable suggestion was skipped due to low confidence.
func (s *Services) GetFMEURL(ctx context.Context, majorVersion int) string { | ||
specs, err := s.PCMS.PlateauSpecs(ctx) | ||
if err != nil { | ||
log.Errorfc(ctx, "cmsintegrationv3: failed to get plateau specs: %v", err) | ||
return "" | ||
} | ||
|
||
for _, spec := range specs { | ||
if spec.FMEURL == "" { | ||
continue | ||
} | ||
|
||
if spec.MajorVersion == majorVersion { | ||
return spec.FMEURL | ||
} | ||
} | ||
|
||
return "" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider returning an error when FME URL retrieval fails
In the GetFMEURL
method, when s.PCMS.PlateauSpecs(ctx)
fails or no matching spec is found, the function logs the error and returns an empty string. This might lead to challenges in error handling for the caller, as they won't be able to distinguish between an actual empty URL and an error condition.
Proposed refactored function:
-func (s *Services) GetFMEURL(ctx context.Context, majorVersion int) string {
+func (s *Services) GetFMEURL(ctx context.Context, majorVersion int) (string, error) {
specs, err := s.PCMS.PlateauSpecs(ctx)
if err != nil {
- log.Errorfc(ctx, "cmsintegrationv3: failed to get plateau specs: %v", err)
- return ""
+ return "", fmt.Errorf("failed to get plateau specs: %w", err)
}
for _, spec := range specs {
if spec.FMEURL == "" {
continue
}
if spec.MajorVersion == majorVersion {
- return spec.FMEURL
+ return spec.FMEURL, nil
}
}
- return ""
+ return "", fmt.Errorf("no FME URL found for major version %d", majorVersion)
}
This change allows the caller to handle errors more effectively by providing explicit error messages.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
func (s *Services) GetFMEURL(ctx context.Context, majorVersion int) string { | |
specs, err := s.PCMS.PlateauSpecs(ctx) | |
if err != nil { | |
log.Errorfc(ctx, "cmsintegrationv3: failed to get plateau specs: %v", err) | |
return "" | |
} | |
for _, spec := range specs { | |
if spec.FMEURL == "" { | |
continue | |
} | |
if spec.MajorVersion == majorVersion { | |
return spec.FMEURL | |
} | |
} | |
return "" | |
} | |
func (s *Services) GetFMEURL(ctx context.Context, majorVersion int) (string, error) { | |
specs, err := s.PCMS.PlateauSpecs(ctx) | |
if err != nil { | |
return "", fmt.Errorf("failed to get plateau specs: %w", err) | |
} | |
for _, spec := range specs { | |
if spec.FMEURL == "" { | |
continue | |
} | |
if spec.MajorVersion == majorVersion { | |
return spec.FMEURL, nil | |
} | |
} | |
return "", fmt.Errorf("no FME URL found for major version %d", majorVersion) | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (1)
server/cmsintegration/cmsintegrationv3/model_test.go (1)
249-256
: LGTM! Consider adding edge cases.The new test function
TestCityItem_SpecMajorVersionInt
is well-structured and covers a good range of input formats for theSpec
field. It effectively tests theSpecMajorVersionInt
method's ability to extract the major version number from various version string formats.To further improve the test coverage, consider adding a few edge cases:
- An empty string:
assert.Equal(t, 0, (&CityItem{Spec: ""}).SpecMajorVersionInt())
- A non-numeric string:
assert.Equal(t, 0, (&CityItem{Spec: "version"}).SpecMajorVersionInt())
- A very large version number:
assert.Equal(t, 9999, (&CityItem{Spec: "第9999版"}).SpecMajorVersionInt())
These additional cases would help ensure the method handles unexpected inputs gracefully.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
- server/cmsintegration/cmsintegrationv3/model.go (3 hunks)
- server/cmsintegration/cmsintegrationv3/model_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- server/cmsintegration/cmsintegrationv3/model.go
Summary by CodeRabbit
New Features
CityItem
struct with a simplified field name and added functionality for version handling.Bug Fixes
Refactor
CMS
andRepos
structures to integrate a new specification store.Tests