• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

decentraland / marketplace / 12537635746

29 Dec 2024 06:09PM UTC coverage: 66.129% (-0.1%) from 66.252%
12537635746

Pull #2344

github

LautaroPetaccio
fix: Owner being shown in the item detail page when the item is L1
Pull Request #2344: fix: Multiple off chain issues

2689 of 5279 branches covered (50.94%)

Branch coverage included in aggregate %.

1 of 2 new or added lines in 2 files covered. (50.0%)

12 existing lines in 5 files now uncovered.

7852 of 10661 relevant lines covered (73.65%)

77.28 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

35.66
/webapp/src/modules/vendor/decentraland/nft/authApi.ts
1
import { NFTCategory, NFTFilters, RentalStatus } from '@dcl/schemas'
2
import { BaseClient } from 'decentraland-dapps/dist/lib/BaseClient'
86✔
3
import { config } from '../../../../config'
86✔
4
import { AssetType } from '../../../asset/types'
5
import { NFTsFetchParams } from '../../../nft/types'
6
import { getNFTSortBy } from '../../../routing/search'
86✔
7
import { FetchOneOptions } from '../../types'
8
import { ATLAS_SERVER_URL } from '../land'
86✔
9
import { NFTsFetchFilters, NFTResponse, NFTResult, OwnersFilters, OwnersResponse } from './types'
10

11
export const NFT_SERVER_URL = config.get('NFT_SERVER_URL')
86✔
12

13
export enum PriceFilterExtraOption {
86✔
14
  LAND = 'land'
15
}
16

17
export type PriceFilterOptions = NFTCategory | PriceFilterExtraOption
18
export type PriceFilters = Omit<NFTsFetchFilters, 'category'> & {
19
  category: NFTCategory | PriceFilterExtraOption
20
  assetType?: AssetType
21
}
22

23
export type EstateSizeFilters = Pick<
24
  NFTFilters,
25
  'isOnSale' | 'adjacentToRoad' | 'minDistanceToPlaza' | 'maxDistanceToPlaza' | 'minPrice' | 'maxPrice'
26
>
27

28
export class NFTAuthAPI extends BaseClient {
66✔
29
  async get(params: NFTsFetchParams, filters?: NFTsFetchFilters): Promise<NFTResponse> {
30
    const queryParams = this.buildNFTQueryString(params, filters)
1✔
31
    return this.fetch(`/v1/nfts?${queryParams}`)
1✔
32
  }
33

34
  async fetchOne(contractAddress: string, tokenId: string, options?: FetchOneOptions): Promise<NFTResult> {
35
    const queryParams = new URLSearchParams()
×
36
    queryParams.append('contractAddress', contractAddress)
×
37
    queryParams.append('tokenId', tokenId)
×
38
    if (options) {
×
39
      Object.entries(options).forEach(([key, value]) =>
×
40
        Array.isArray(value)
×
41
          ? value.filter(v => v !== undefined).forEach(aValue => queryParams.append(key, aValue))
×
42
          : value !== undefined
×
43
            ? queryParams.append(key, value)
44
            : null
45
      )
46
    }
NEW
47
    const response: NFTResponse = await this.fetch(`/v1/nfts?${queryParams.toString()}`, { cache: 'reload' })
×
48

49
    if (response.data.length === 0) {
×
50
      throw new Error('Not found')
×
51
    }
52

53
    return response.data[0]
×
54
  }
55

56
  async fetchTokenId(x: number, y: number) {
57
    try {
×
58
      const { id } = await fetch(`${ATLAS_SERVER_URL}/v2/parcels/${x}/${y}`).then(resp => resp.json())
×
59
      return id as string
×
60
    } catch (error) {
61
      return null
×
62
    }
63
  }
64

65
  private appendNFTFiltersToQueryParams(queryParams: URLSearchParams, filters: NFTsFetchFilters): void {
66
    if (filters.rarities) {
1!
67
      for (const rarity of filters.rarities) {
×
68
        queryParams.append('itemRarity', rarity)
×
69
      }
70
    }
71
    if (filters.isLand) {
1!
72
      queryParams.append('isLand', 'true')
×
73
    }
74
    if (filters.isWearableHead) {
1!
75
      queryParams.append('isWearableHead', 'true')
×
76
    }
77
    if (filters.isWearableAccessory) {
1!
78
      queryParams.append('isWearableAccessory', 'true')
×
79
    }
80
    if (filters.isWearableSmart) {
1!
81
      queryParams.append('isWearableSmart', 'true')
×
82
    }
83
    if (filters.wearableCategory) {
1!
84
      queryParams.append('wearableCategory', filters.wearableCategory)
×
85
    }
86
    if (filters.emoteCategory) {
1!
87
      queryParams.append('emoteCategory', filters.emoteCategory)
×
88
    }
89
    if (filters.wearableGenders) {
1!
90
      for (const wearableGender of filters.wearableGenders) {
×
91
        queryParams.append('wearableGender', wearableGender)
×
92
      }
93
    }
94
    if (filters.network) {
1!
95
      queryParams.append('network', filters.network)
×
96
    }
97

98
    if (filters.emotePlayMode) {
1!
99
      for (const emotePlayMode of filters.emotePlayMode) {
×
100
        queryParams.append('emotePlayMode', emotePlayMode)
×
101
      }
102
    }
103

104
    if (filters.tenant) {
1!
105
      queryParams.append('tenant', filters.tenant)
×
106
    }
107

108
    if (filters.rentalStatus) {
1!
109
      const statuses: RentalStatus[] = !Array.isArray(filters.rentalStatus) ? [filters.rentalStatus] : filters.rentalStatus
×
110
      statuses.forEach(status => queryParams.append('rentalStatus', status))
×
111
    }
112

113
    if (filters.creator) {
1!
114
      const creators = Array.isArray(filters.creator) ? filters.creator : [filters.creator]
×
115
      creators.forEach(creator => queryParams.append('creator', creator))
×
116
    }
117

118
    if (filters.contracts && filters.contracts.length > 0) {
1!
119
      for (const contract of filters.contracts) {
×
120
        queryParams.append('contractAddress', contract)
×
121
      }
122
    }
123
    if (filters.minPrice) {
1!
124
      queryParams.append('minPrice', filters.minPrice)
×
125
    }
126

127
    if (filters.maxPrice) {
1!
128
      queryParams.append('maxPrice', filters.maxPrice)
×
129
    }
130
    if (filters.minEstateSize) {
1!
131
      queryParams.append('minEstateSize', filters.minEstateSize)
×
132
    }
133

134
    if (filters.maxEstateSize) {
1!
135
      queryParams.append('maxEstateSize', filters.maxEstateSize)
×
136
    }
137

138
    if (filters.minDistanceToPlaza) {
1!
139
      queryParams.append('minDistanceToPlaza', filters.minDistanceToPlaza)
×
140
    }
141

142
    if (filters.maxDistanceToPlaza) {
1!
143
      queryParams.append('maxDistanceToPlaza', filters.maxDistanceToPlaza)
×
144
    }
145

146
    if (filters.adjacentToRoad) {
1!
147
      queryParams.append('adjacentToRoad', 'true')
×
148
    }
149

150
    if (filters.rentalDays) {
1!
151
      for (const rentalDay of filters.rentalDays) {
×
152
        queryParams.append('rentalDays', rentalDay.toString())
×
153
      }
154
    }
155
  }
156

157
  private buildNFTQueryString(params: NFTsFetchParams, filters?: NFTsFetchFilters): string {
158
    const queryParams = new URLSearchParams()
1✔
159
    queryParams.append('first', params.first.toString())
1✔
160
    queryParams.append('skip', params.skip.toString())
1✔
161
    if (params.orderBy) {
1!
162
      queryParams.append('sortBy', getNFTSortBy(params.orderBy))
×
163
    }
164
    if (params.category) {
1!
165
      queryParams.append('category', params.category)
×
166
    }
167
    if (params.address) {
1✔
168
      queryParams.append('owner', params.address)
1✔
169
    }
170
    if (params.onlyOnSale) {
1✔
171
      queryParams.append('isOnSale', 'true')
1✔
172
    }
173
    if (params.onlyOnRent) {
1!
174
      queryParams.append('isOnRent', 'true')
×
175
    }
176
    if (params.search) {
1!
177
      queryParams.set('search', params.search)
×
178
    }
179
    if (filters) {
1✔
180
      this.appendNFTFiltersToQueryParams(queryParams, filters)
1✔
181
    }
182

183
    return queryParams.toString()
1✔
184
  }
185

186
  async getOwners(params: OwnersFilters): Promise<{ data: OwnersResponse[]; total: number }> {
187
    const queryParams = this.buildGetOwnersParams(params)
×
188
    return this.fetch(`/v1/owners?${queryParams}`)
×
189
  }
190

191
  private buildGetOwnersParams(filters: OwnersFilters): string {
192
    const queryParams = new URLSearchParams()
×
193

194
    const entries = Object.entries(filters)
×
195

196
    for (const [key, value] of entries) {
×
197
      queryParams.append(key, value.toString())
×
198
    }
199

200
    return queryParams.toString()
×
201
  }
202
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc