Skip to content
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: introduce logic to fetch catalog from the marketplace-server #1967

Merged
merged 11 commits into from
Nov 8, 2023
1 change: 1 addition & 0 deletions webapp/src/components/AssetCard/AssetCard.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
}

.ui.card.AssetCard.catalog {
overflow: hidden;
height: 360px;
}

Expand Down
123 changes: 92 additions & 31 deletions webapp/src/modules/favorites/sagas.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
import { locations } from '../routing/locations'
import { SortDirection } from '../routing/types'
import { CatalogAPI } from '../vendor/decentraland/catalog/api'
import { getIsMarketplaceServerEnabled } from '../features/selectors'
import { getData as getItemsData } from '../item/selectors'
import {
BULK_PICK_SUCCESS,
Expand Down Expand Up @@ -100,7 +101,8 @@ describe('when handling the request for fetching favorited items', () => {
return expectSaga(favoritesSaga, getIdentity)
.provide([
[select(getListId), listId],
[select(getAddress), Promise.reject(error)]
[select(getAddress), Promise.reject(error)],
[select(getIsMarketplaceServerEnabled), true]
])
.put(fetchFavoritedItemsFailure(error.message))
.dispatch(fetchFavoritedItemsRequest(options))
Expand All @@ -114,6 +116,7 @@ describe('when handling the request for fetching favorited items', () => {
.provide([
[select(getListId), listId],
[select(getAddress), address],
[select(getIsMarketplaceServerEnabled), true],
[call(getAccountIdentity), Promise.reject(error)]
])
.put(fetchFavoritedItemsFailure(error.message))
Expand All @@ -129,6 +132,7 @@ describe('when handling the request for fetching favorited items', () => {
.provide([
[select(getListId), listId],
[select(getAddress), address],
[select(getIsMarketplaceServerEnabled), true],
[call(getAccountIdentity), Promise.resolve()],
[
matchers.call.fn(FavoritesAPI.prototype.getPicksByList),
Expand All @@ -149,6 +153,7 @@ describe('when handling the request for fetching favorited items', () => {
let favoritedItemIds: FavoritedItems
let createdAt: Record<string, number>
let total: number
let isMarketplaceFFOn: boolean

describe("and there's more than one favorited item", () => {
beforeEach(() => {
Expand All @@ -157,35 +162,79 @@ describe('when handling the request for fetching favorited items', () => {
total = 1
})

describe('and the call to the items api fails', () => {
it('should dispatch an action signaling the failure of the handled action', () => {
return expectSaga(favoritesSaga, getIdentity)
.provide([
[select(getListId), listId],
[select(getAddress), address],
[call(getAccountIdentity), Promise.resolve()],
[
matchers.call.fn(FavoritesAPI.prototype.getPicksByList),
Promise.resolve({ results: favoritedItemIds, total })
],
[
matchers.call.fn(CatalogAPI.prototype.get),
Promise.reject(error)
]
])
.call.like({
fn: CatalogAPI.prototype.get,
args: [
{
...options.filters,
first: 1,
ids: [favoritedItemIds[0].itemId]
}
]
})
.put(fetchFavoritedItemsFailure(error.message))
.dispatch(fetchFavoritedItemsRequest(options))
.run({ silenceTimeout: true })
describe('and the marketplace-server flag is off', () => {
beforeEach(() => {
isMarketplaceFFOn = false
})
describe('and the call to the items api fails', () => {
it('should dispatch an action signaling the failure of the handled action', () => {
return expectSaga(favoritesSaga, getIdentity)
.provide([
[select(getListId), listId],
[select(getIsMarketplaceServerEnabled), isMarketplaceFFOn],
[select(getAddress), address],
[call(getAccountIdentity), Promise.resolve()],
[
matchers.call.fn(FavoritesAPI.prototype.getPicksByList),
Promise.resolve({ results: favoritedItemIds, total })
],
[
matchers.call.fn(CatalogAPI.prototype.get),
Promise.reject(error)
]
])
.call.like({
fn: CatalogAPI.prototype.get,
args: [
{
...options.filters,
first: 1,
ids: [favoritedItemIds[0].itemId]
}
]
})
.put(fetchFavoritedItemsFailure(error.message))
.dispatch(fetchFavoritedItemsRequest(options))
.run({ silenceTimeout: true })
})
})
})

describe('and the marketplace-server flag is on', () => {
beforeEach(() => {
isMarketplaceFFOn = true
})
describe('and the call to the items api fails', () => {
it('should dispatch an action signaling the failure of the handled action', () => {
return expectSaga(favoritesSaga, getIdentity)
.provide([
[select(getListId), listId],
[select(getIsMarketplaceServerEnabled), isMarketplaceFFOn],
[select(getAddress), address],
[call(getAccountIdentity), Promise.resolve()],
[
matchers.call.fn(FavoritesAPI.prototype.getPicksByList),
Promise.resolve({ results: favoritedItemIds, total })
],
[
matchers.call.fn(CatalogAPI.prototype.get),
Promise.reject(error)
]
])
.call.like({
fn: CatalogAPI.prototype.get,
args: [
{
...options.filters,
first: 1,
ids: [favoritedItemIds[0].itemId]
}
]
})
.put(fetchFavoritedItemsFailure(error.message))
.dispatch(fetchFavoritedItemsRequest(options))
.run({ silenceTimeout: true })
})
})
})

Expand All @@ -202,6 +251,7 @@ describe('when handling the request for fetching favorited items', () => {
.provide([
[select(getListId), listId],
[select(getAddress), address],
[select(getIsMarketplaceServerEnabled), true],
[call(getAccountIdentity), Promise.resolve()],
[
matchers.call.fn(FavoritesAPI.prototype.getPicksByList),
Expand Down Expand Up @@ -256,6 +306,7 @@ describe('when handling the request for fetching favorited items', () => {
.provide([
[select(getListId), listId],
[select(getAddress), address],
[select(getIsMarketplaceServerEnabled), true],
[call(getAccountIdentity), Promise.resolve()],
[
matchers.call.fn(FavoritesAPI.prototype.getPicksByList),
Expand Down Expand Up @@ -296,6 +347,7 @@ describe('when handling the request for fetching favorited items', () => {
.provide([
[select(getListId), listId],
[select(getAddress), null],
[select(getIsMarketplaceServerEnabled), true],
[
matchers.call.fn(FavoritesAPI.prototype.getPicksByList),
Promise.reject(error)
Expand Down Expand Up @@ -329,6 +381,7 @@ describe('when handling the request for fetching favorited items', () => {
.provide([
[select(getListId), listId],
[select(getAddress), null],
[select(getIsMarketplaceServerEnabled), true],
[
matchers.call.fn(FavoritesAPI.prototype.getPicksByList),
Promise.resolve({ results: favoritedItemIds, total })
Expand Down Expand Up @@ -367,6 +420,7 @@ describe('when handling the request for fetching favorited items', () => {
.provide([
[select(getListId), listId],
[select(getAddress), null],
[select(getIsMarketplaceServerEnabled), true],
[
matchers.call.fn(FavoritesAPI.prototype.getPicksByList),
Promise.resolve({ results: favoritedItemIds, total })
Expand Down Expand Up @@ -420,6 +474,7 @@ describe('when handling the request for fetching favorited items', () => {
.provide([
[select(getListId), listId],
[select(getAddress), null],
[select(getIsMarketplaceServerEnabled), true],
[
matchers.call.fn(FavoritesAPI.prototype.getPicksByList),
{ results: favoritedItemIds, total }
Expand Down Expand Up @@ -611,11 +666,12 @@ describe('when handling the request for fetching lists', () => {
]
})

describe('and there are not items in the state', () => {
describe('and there are no items in the state', () => {
it('should dispatch an action signaling the success of the handled action', () => {
return expectSaga(favoritesSaga, getIdentity)
.provide([
[call(getAccountIdentity), Promise.resolve()],
[select(getIsMarketplaceServerEnabled), true],
[
matchers.call.fn(FavoritesAPI.prototype.getLists),
Promise.resolve({ results: lists, total })
Expand Down Expand Up @@ -660,6 +716,7 @@ describe('when handling the request for fetching lists', () => {
return expectSaga(favoritesSaga, getIdentity)
.provide([
[call(getAccountIdentity), Promise.resolve()],
[select(getIsMarketplaceServerEnabled), true],
[
matchers.call.fn(FavoritesAPI.prototype.getLists),
Promise.resolve({ results: lists, total })
Expand Down Expand Up @@ -757,6 +814,7 @@ describe('when handling the request for fetching lists', () => {
return expectSaga(favoritesSaga, getIdentity)
.provide([
[call(getAccountIdentity), Promise.resolve()],
[select(getIsMarketplaceServerEnabled), true],
[
matchers.call.fn(FavoritesAPI.prototype.getLists),
Promise.resolve({ results: lists, total })
Expand Down Expand Up @@ -804,6 +862,7 @@ describe('when handling the request for fetching lists', () => {
return expectSaga(favoritesSaga, getIdentity)
.provide([
[call(getAccountIdentity), Promise.resolve()],
[select(getIsMarketplaceServerEnabled), true],
[
matchers.call.fn(FavoritesAPI.prototype.getLists),
Promise.resolve({ results: lists, total })
Expand Down Expand Up @@ -1034,6 +1093,7 @@ describe('when handling the request for getting a list', () => {
matchers.call.fn(FavoritesAPI.prototype.getList),
Promise.resolve(list)
],
[select(getIsMarketplaceServerEnabled), true],
[select(getItemsData), {}],
[
matchers.call.fn(CatalogAPI.prototype.get),
Expand Down Expand Up @@ -1078,6 +1138,7 @@ describe('when handling the request for getting a list', () => {
matchers.call.fn(FavoritesAPI.prototype.getList),
Promise.resolve(list)
],
[select(getIsMarketplaceServerEnabled), true],
[select(getItemsData), { anotherItemId: {} }],
[
matchers.call.fn(CatalogAPI.prototype.get),
Expand Down
24 changes: 18 additions & 6 deletions webapp/src/modules/favorites/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { getIdentity as getAccountIdentity } from '../identity/utils'
import { CatalogAPI } from '../vendor/decentraland/catalog/api'
import { retryParams } from '../vendor/decentraland/utils'
import { getAddress } from '../wallet/selectors'
import { NFT_SERVER_URL } from '../vendor/decentraland'
import { MARKETPLACE_SERVER_URL, NFT_SERVER_URL } from '../vendor/decentraland'
import { locations } from '../routing/locations'
import { SortDirection } from '../routing/types'
import { ListsSortBy } from '../vendor/decentraland/favorites/types'
Expand Down Expand Up @@ -83,6 +83,7 @@ import {
import { convertListsBrowseSortByIntoApiSortBy } from './utils'
import { List } from './types'
import { getData as getItemsData } from '../item/selectors'
import { getIsMarketplaceServerEnabled } from '../features/selectors'

export function* favoritesSaga(getIdentity: () => AuthIdentity | undefined) {
const API_OPTS = {
Expand All @@ -95,6 +96,10 @@ export function* favoritesSaga(getIdentity: () => AuthIdentity | undefined) {
API_OPTS
)
const catalogAPI = new CatalogAPI(NFT_SERVER_URL, API_OPTS)
const marketplaceServerCatalogAPI = new CatalogAPI(
MARKETPLACE_SERVER_URL,
API_OPTS
)

yield takeEvery(
FETCH_FAVORITED_ITEMS_REQUEST,
Expand All @@ -114,6 +119,13 @@ export function* favoritesSaga(getIdentity: () => AuthIdentity | undefined) {
handleBulkPickSuccessOrFailure
)

function* getCatalogAPI() {
const isMarketplaceServerEnabled: boolean = yield select(
getIsMarketplaceServerEnabled
)
return isMarketplaceServerEnabled ? marketplaceServerCatalogAPI : catalogAPI
}

function* fetchPreviewItems(previewListsItemIds: string[]) {
let previewItems: Item[] = []

Expand All @@ -127,10 +139,8 @@ export function* favoritesSaga(getIdentity: () => AuthIdentity | undefined) {
ids: previewListsItemIds
}

const result: { data: Item[] } = yield call(
[catalogAPI, 'get'],
itemFilters
)
const api: CatalogAPI = yield call(getCatalogAPI)
const result: { data: Item[] } = yield call([api, 'get'], itemFilters)
previewItems = result.data
}
}
Expand Down Expand Up @@ -173,9 +183,11 @@ export function* favoritesSaga(getIdentity: () => AuthIdentity | undefined) {
filters: optionsFilters
}

const api: CatalogAPI = yield call(getCatalogAPI)

if (results.length > 0) {
const result: { data: Item[] } = yield call(
[catalogAPI, 'get'],
[api, 'get'],
optionsFilters
)
items = result.data
Expand Down
10 changes: 10 additions & 0 deletions webapp/src/modules/features/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,13 @@ export const getIsNewNavbarDropdownEnabled = (state: RootState) => {
}
return false
}
export const getIsMarketplaceServerEnabled = (state: RootState) => {
if (hasLoadedInitialFlags(state)) {
return getIsFeatureEnabled(
state,
ApplicationName.MARKETPLACE,
FeatureName.MARKETPLACE_SERVER
)
}
return false
}
5 changes: 3 additions & 2 deletions webapp/src/modules/features/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ export enum FeatureName {
MAP_VIEW_FILTERS = 'map-view-filters',
RENTAL_PRICE_FILTER_CHART = 'rental-price-fitler-chart',
HANDS_CATEGORY = 'hands-category',
SMART_WEARABLES_FTU = 'smart-wearables-ftu',
EMOTES_V2 = 'emotes-2.0',
EMOTES_V2_FTU = 'emotes-2.0-ftu',
NEW_NAVBAR_DROPDOWN = 'new-navbar-dropdown'
NEW_NAVBAR_DROPDOWN = 'new-navbar-dropdown',
SMART_WEARABLES_FTU = 'smart-wearables-ftu',
MARKETPLACE_SERVER = 'marketplace-server'
}
32 changes: 32 additions & 0 deletions webapp/src/modules/features/utils.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { expectSaga } from 'redux-saga-test-plan'
import { select } from 'redux-saga/effects'
import { isLoadingFeatureFlags } from 'decentraland-dapps/dist/modules/features/selectors'
import {
FETCH_APPLICATION_FEATURES_FAILURE,
FETCH_APPLICATION_FEATURES_SUCCESS
} from 'decentraland-dapps/dist/modules/features/actions'
import { waitForFeatureFlagsToBeLoaded } from './utils'

describe('waitForFeatureFlagsToBeLoaded Util', () => {
it('should do nothing if feature flags are already loaded', () => {
return expectSaga(waitForFeatureFlagsToBeLoaded)
.provide([[select(isLoadingFeatureFlags), false]])
.not.take(FETCH_APPLICATION_FEATURES_SUCCESS)
.not.take(FETCH_APPLICATION_FEATURES_FAILURE)
.run()
})

it('should wait for FETCH_APPLICATION_FEATURES_SUCCESS if feature flags are being fetched', () => {
return expectSaga(waitForFeatureFlagsToBeLoaded)
.provide([[select(isLoadingFeatureFlags), true]])
.take(FETCH_APPLICATION_FEATURES_SUCCESS)
.run()
})

it('should wait for FETCH_APPLICATION_FEATURES_FAILURE if feature flags are being fetched and there is an error', () => {
return expectSaga(waitForFeatureFlagsToBeLoaded)
.provide([[select(isLoadingFeatureFlags), true]])
.take(FETCH_APPLICATION_FEATURES_FAILURE)
.run()
})
})
Loading
Loading