Skip to content

Commit

Permalink
feat: implement redirect query (#1746)
Browse files Browse the repository at this point in the history
## What's the purpose of this pull request?

This PR adds a query to solve redirects when performing a search.
In case of VTEX platform, this is solved by the IS api.


## How it works?

When performing a search if a term or facet has a redirect, the value of
the `redirect` field should be an URL; this can later be used to
redirect the user to an internal or external URL.

From VTEX admin:
<img width="795" alt="Screenshot 2023-05-04 at 17 51 48"
src="https://user-images.githubusercontent.com/50715158/236261672-24230b76-3f5e-4f92-8c17-53111fd65f24.png">

It get solved as:
<img width="1474" alt="image"
src="https://github.com/vtex/faststore/assets/67066494/4cecfa15-200b-49a0-a070-e4226f57c71e">

## How to test it?

- Run the `@faststore/api` package individually.
- Browse [localhost/graphql](http://localhost:4000/graphql)
- Run the redirect query with a term that is active in
`/admin/search/v4/redirects/`
- For storeframework, you can use the term `tech`

PR related at vtex-sites:
vtex-sites/nextjs.store#382
PR related 2.x: #1749

---------

Co-authored-by: beatrizmaselli <[email protected]>
  • Loading branch information
Git-the-Sanz and beatrizmaselli authored May 9, 2023
1 parent 950ce98 commit d9b0ace
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 3 deletions.
40 changes: 40 additions & 0 deletions packages/api/mocks/RedirectQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
export const RedirectQueryTermTech = `query RedirectSearch {
redirect(term: "tech") {
url
}
}
`

export const redirectTermTechFetch = {
info: 'https://storeframework.vtexcommercestable.com.br/api/io/_v/api/intelligent-search/product_search/trade-policy/1?page=2&count=1&query=tech&sort=&fuzzy=auto&locale=en-US&hideUnavailableItems=false',
init: undefined,
result: {
products: [],
recordsFiltered: 0,
fuzzy: 'auto',
operator: 'and',
redirect: '/technology',
translated: false,
pagination: {
count: 1,
current: {
index: 0,
},
before: [],
after: [],
perPage: 0,
next: {
index: 0,
},
previous: {
index: 0,
},
first: {
index: 0,
},
last: {
index: 0,
},
},
},
}
18 changes: 18 additions & 0 deletions packages/api/src/__generated__/schema.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 25 additions & 3 deletions packages/api/src/platforms/vtex/resolvers/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type {
QueryProductArgs,
QuerySearchArgs,
QueryShippingArgs,
QueryRedirectArgs
} from "../../../__generated__/schema"
import type { CategoryTree } from "../clients/commerce/types/CategoryTree"
import type { Context } from "../index"
Expand Down Expand Up @@ -142,9 +143,8 @@ export const Query = {
productId: crossSelling.value,
})

query = `product:${
products.map((x) => x.productId).slice(0, first).join(";")
}`
query = `product:${products.map((x) => x.productId).slice(0, first).join(";")
}`
}

const after = maybeAfter ? Number(maybeAfter) : 0
Expand Down Expand Up @@ -273,4 +273,26 @@ export const Query = {
address,
}
},
redirect: async (
_: unknown,
{ term, selectedFacets }: QueryRedirectArgs,
ctx: Context
) => {
// Currently the search redirection can be done through a search term or filter (facet) so we limit the redirect query to always have one of these values otherwise we do not execute it.
// https://help.vtex.com/en/tracks/vtex-intelligent-search--19wrbB7nEQcmwzDPl1l4Cb/4Gd2wLQFbCwTsh8RUDwSoL?&utm_source=autocomplete
if (!term && (!selectedFacets || !selectedFacets.length)) {
return null
}

const { redirect } = await ctx.clients.search.products({
page: 1,
count: 1,
query: term ?? undefined,
selectedFacets: selectedFacets?.flatMap(transformSelectedFacet) ?? [],
})

return {
url: redirect
}
},
}
26 changes: 26 additions & 0 deletions packages/api/src/typeDefs/query.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -282,4 +282,30 @@ type Query {
country: String!
): ShippingData
@cacheControl(scope: "public", sMaxAge: 120, staleWhileRevalidate: 3600)

"""
Returns if there's a redirect for a search.
"""
redirect(
"""
Search term.
"""
term: String
"""
Array of selected search facets.
"""
selectedFacets: [IStoreSelectedFacet!]
): StoreRedirect
@cacheControl(scope: "public", sMaxAge: 120, staleWhileRevalidate: 3600)
}

"""
Redirect informations, including url returned by the query.
https://schema.org/Thing
"""
type StoreRedirect {
"""
URL to redirect
"""
url: String
}
10 changes: 10 additions & 0 deletions packages/api/test/__snapshots__/queries.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1167,3 +1167,13 @@ Object {
},
}
`;

exports[`\`redirect\` query 1`] = `
Object {
"data": Object {
"redirect": Object {
"url": "/technology",
},
},
}
`;
25 changes: 25 additions & 0 deletions packages/api/test/queries.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ import {
addressFetch,
ShippingSimulationQueryResult,
} from '../mocks/ShippingQuery'
import {
RedirectQueryTermTech,
redirectTermTechFetch,
} from '../mocks/RedirectQuery'

const apiOptions = {
platform: 'vtex',
Expand Down Expand Up @@ -236,3 +240,24 @@ test('`shipping` query', async () => {

expect(response).toMatchSnapshot()
})

test('`redirect` query', async () => {
const fetchAPICalls = [redirectTermTechFetch]

mockedFetch.mockImplementation((info, init) =>
pickFetchAPICallResult(info, init, fetchAPICalls)
)

const response = await run(RedirectQueryTermTech)

expect(mockedFetch).toHaveBeenCalledTimes(1)

fetchAPICalls.forEach((fetchAPICall) => {
expect(mockedFetch).toHaveBeenCalledWith(
fetchAPICall.info,
fetchAPICall.init
)
})

expect(response).toMatchSnapshot()
})
1 change: 1 addition & 0 deletions packages/api/test/schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const QUERIES = [
'allProducts',
'allCollections',
'shipping',
'redirect',
]

const MUTATIONS = ['validateCart', 'validateSession', 'subscribeToNewsletter']
Expand Down

0 comments on commit d9b0ace

Please sign in to comment.