Skip to content

Commit 10c5f9d

Browse files
authored
Add adapter logic for GetSavedSearch (#1274)
This will be used by the [getSavedSearch](https://github.com/GoogleChrome/webstatus.dev/blob/078beb7fecb7c22cdd3eb2dbd3c814eb2e84beb9/openapi/backend/openapi.yaml#L783) http handler This is the layer between the httpserver and spanner. It parses out the error if the: - The entity does not exist - General error
1 parent 6354558 commit 10c5f9d

File tree

2 files changed

+154
-0
lines changed

2 files changed

+154
-0
lines changed

lib/gcpspanner/spanneradapters/backend.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,29 @@ func (s *Backend) DeleteUserSavedSearch(ctx context.Context, userID, savedSearch
451451
return nil
452452
}
453453

454+
func (s *Backend) GetSavedSearch(ctx context.Context, savedSearchID string, userID *string) (
455+
*backend.SavedSearchResponse, error) {
456+
savedSearch, err := s.client.GetUserSavedSearch(ctx, savedSearchID, userID)
457+
if err != nil {
458+
if errors.Is(err, gcpspanner.ErrQueryReturnedNoResults) {
459+
return nil, errors.Join(err, backendtypes.ErrEntityDoesNotExist)
460+
}
461+
462+
return nil, err
463+
}
464+
465+
return &backend.SavedSearchResponse{
466+
Id: savedSearch.ID,
467+
CreatedAt: savedSearch.CreatedAt,
468+
UpdatedAt: savedSearch.UpdatedAt,
469+
Name: savedSearch.Name,
470+
Query: savedSearch.Query,
471+
Description: savedSearch.Description,
472+
BookmarkStatus: convertSavedSearchIsBookmarkedFromGCP(savedSearch.IsBookmarked),
473+
Permissions: convertSavedSearchRoleFromGCP(savedSearch.Role),
474+
}, nil
475+
}
476+
454477
func convertBaselineStatusBackendToSpanner(status backend.BaselineInfoStatus) gcpspanner.BaselineStatus {
455478
switch status {
456479
case backend.Widely:

lib/gcpspanner/spanneradapters/backend_test.go

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1646,6 +1646,137 @@ func TestDeleteUserSavedSearch(t *testing.T) {
16461646
}
16471647
}
16481648

1649+
func TestGetSavedSearch(t *testing.T) {
1650+
testCases := []struct {
1651+
name string
1652+
cfg *mockGetUserSavedSearchConfig
1653+
userID *string
1654+
savedSearchID string
1655+
expectedOutput *backend.SavedSearchResponse
1656+
expectedError error
1657+
}{
1658+
{
1659+
name: "success authenticated user",
1660+
userID: valuePtr("user1"),
1661+
savedSearchID: "saved-search-id",
1662+
cfg: &mockGetUserSavedSearchConfig{
1663+
expectedAuthenticatedUserID: valuePtr("user1"),
1664+
expectedSavedSearchID: "saved-search-id",
1665+
result: &gcpspanner.UserSavedSearch{
1666+
SavedSearch: gcpspanner.SavedSearch{
1667+
Name: "test search",
1668+
Description: valuePtr("test description"),
1669+
Query: "test query",
1670+
Scope: gcpspanner.UserPublicScope,
1671+
AuthorID: "user1",
1672+
CreatedAt: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC),
1673+
UpdatedAt: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC),
1674+
ID: "saved-search-id",
1675+
},
1676+
Role: valuePtr(string(gcpspanner.SavedSearchOwner)),
1677+
IsBookmarked: valuePtr(true),
1678+
},
1679+
returnedError: nil,
1680+
},
1681+
expectedOutput: &backend.SavedSearchResponse{
1682+
Id: "saved-search-id",
1683+
CreatedAt: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC),
1684+
UpdatedAt: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC),
1685+
Name: "test search",
1686+
Query: "test query",
1687+
Description: valuePtr("test description"),
1688+
BookmarkStatus: &backend.UserSavedSearchBookmark{
1689+
Status: backend.BookmarkActive,
1690+
},
1691+
Permissions: &backend.UserSavedSearchPermissions{
1692+
Role: valuePtr(backend.SavedSearchOwner),
1693+
},
1694+
},
1695+
expectedError: nil,
1696+
},
1697+
{
1698+
name: "success unauthenticated user",
1699+
userID: nil,
1700+
savedSearchID: "saved-search-id",
1701+
cfg: &mockGetUserSavedSearchConfig{
1702+
expectedAuthenticatedUserID: nil,
1703+
expectedSavedSearchID: "saved-search-id",
1704+
result: &gcpspanner.UserSavedSearch{
1705+
SavedSearch: gcpspanner.SavedSearch{
1706+
Name: "test search",
1707+
Description: valuePtr("test description"),
1708+
Query: "test query",
1709+
Scope: gcpspanner.UserPublicScope,
1710+
AuthorID: "user1",
1711+
CreatedAt: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC),
1712+
UpdatedAt: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC),
1713+
ID: "saved-search-id",
1714+
},
1715+
Role: nil,
1716+
IsBookmarked: nil,
1717+
},
1718+
returnedError: nil,
1719+
},
1720+
expectedOutput: &backend.SavedSearchResponse{
1721+
Id: "saved-search-id",
1722+
CreatedAt: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC),
1723+
UpdatedAt: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC),
1724+
Name: "test search",
1725+
Query: "test query",
1726+
Description: valuePtr("test description"),
1727+
BookmarkStatus: nil,
1728+
Permissions: nil,
1729+
},
1730+
expectedError: nil,
1731+
},
1732+
{
1733+
name: "search not found error",
1734+
userID: nil,
1735+
savedSearchID: "saved-search-id",
1736+
cfg: &mockGetUserSavedSearchConfig{
1737+
expectedAuthenticatedUserID: nil,
1738+
expectedSavedSearchID: "saved-search-id",
1739+
result: nil,
1740+
returnedError: gcpspanner.ErrQueryReturnedNoResults,
1741+
},
1742+
expectedOutput: nil,
1743+
expectedError: backendtypes.ErrEntityDoesNotExist,
1744+
},
1745+
{
1746+
name: "general error",
1747+
userID: nil,
1748+
savedSearchID: "saved-search-id",
1749+
cfg: &mockGetUserSavedSearchConfig{
1750+
expectedAuthenticatedUserID: nil,
1751+
expectedSavedSearchID: "saved-search-id",
1752+
result: nil,
1753+
returnedError: errTest,
1754+
},
1755+
expectedOutput: nil,
1756+
expectedError: errTest,
1757+
},
1758+
}
1759+
for _, tc := range testCases {
1760+
t.Run(tc.name, func(t *testing.T) {
1761+
//nolint: exhaustruct
1762+
mock := mockBackendSpannerClient{
1763+
t: t,
1764+
mockGetUserSavedSearchCfg: tc.cfg,
1765+
}
1766+
bk := NewBackend(mock)
1767+
output, err := bk.GetSavedSearch(context.Background(), tc.savedSearchID, tc.userID)
1768+
1769+
if !errors.Is(err, tc.expectedError) {
1770+
t.Errorf("unexpected error %s", err)
1771+
}
1772+
1773+
if !reflect.DeepEqual(output, tc.expectedOutput) {
1774+
t.Errorf("unexpected output %v", output)
1775+
}
1776+
})
1777+
}
1778+
}
1779+
16491780
func TestGetFeatureSearchSortOrder(t *testing.T) {
16501781
sortOrderTests := []struct {
16511782
input *backend.ListFeaturesParamsSort

0 commit comments

Comments
 (0)