diff --git a/src/schema/v2/artwork/__tests__/artwork.test.js b/src/schema/v2/artwork/__tests__/artwork.test.js index 7e7b7cb18c..8aeaef2740 100644 --- a/src/schema/v2/artwork/__tests__/artwork.test.js +++ b/src/schema/v2/artwork/__tests__/artwork.test.js @@ -6,17 +6,12 @@ import { getMicrofunnelDataByArtworkInternalID } from "schema/v2/artist/targetSu import { runQuery } from "schema/v2/test/utils" import { CHECKOUT_TAXES_DOC_URL } from "../taxInfo" import { runAuthenticatedQuery } from "schema/v2/test/utils" -import { isFeatureFlagEnabled } from "lib/featureFlags" import config from "config" jest.mock("schema/v2/artist/targetSupply/utils/getMicrofunnelData") -jest.mock("lib/featureFlags", () => ({ - isFeatureFlagEnabled: jest.fn(), -})) /** * @type {jest.Mock} */ -const mockIsFeatureFlagEnabled = isFeatureFlagEnabled describe("Artwork type", () => { const sale = { id: "existy" } @@ -2014,6 +2009,7 @@ describe("Artwork type", () => { }) }) }) + describe("#inquiryQuestions", () => { const query = ` { @@ -2082,6 +2078,7 @@ describe("Artwork type", () => { }) }) }) + describe("markdown fields", () => { describe("#signature", () => { const query = ` @@ -4684,547 +4681,515 @@ describe("Artwork type", () => { context.relatedShowsLoader.mockResolvedValue({ body: [] }) }) - describe("feature flags enabled", () => { + describe("purchasable artwork", () => { beforeEach(() => { - mockIsFeatureFlagEnabled.mockReturnValue(true) + artwork.purchasable = true + artwork.sale_ids = [] }) + it("returns the increasedInterest signal", async () => { + artwork.increased_interest_signal = true - describe("purchasable artwork", () => { - beforeEach(() => { - artwork.purchasable = true - artwork.sale_ids = [] - }) - it("returns the increasedInterest signal", async () => { - artwork.increased_interest_signal = true - - let data = await runQuery(query, context) + let data = await runQuery(query, context) - expect(data.artwork.collectorSignals.increasedInterest).toEqual(true) + expect(data.artwork.collectorSignals.increasedInterest).toEqual(true) - artwork.increased_interest_signal = false + artwork.increased_interest_signal = false - data = await runQuery(query, context) + data = await runQuery(query, context) - expect(data.artwork.collectorSignals.increasedInterest).toEqual(false) + expect(data.artwork.collectorSignals.increasedInterest).toEqual(false) + }) + it("fetches & returns the user-specific collector signals for a purchasable artwork if requested by a logged-in user", async () => { + context.userID = "user-id" + context.mePartnerOffersLoader.mockResolvedValue({ + body: [{ endAt: "2023-01-01T00:00:00Z", active: true }], }) - it("fetches & returns the user-specific collector signals for a purchasable artwork if requested by a logged-in user", async () => { - context.userID = "user-id" - context.mePartnerOffersLoader.mockResolvedValue({ - body: [{ endAt: "2023-01-01T00:00:00Z", active: true }], - }) - - const data = await runQuery(query, context) - expect(context.mePartnerOffersLoader).toHaveBeenCalledWith({ - artwork_id: "richard-prince-untitled-portrait", - size: 1, - sort: "-created_at", - }) + const data = await runQuery(query, context) - expect(data.artwork.collectorSignals.partnerOffer).toEqual({ - endAt: "2023-01-01T00:00:00Z", - }) + expect(context.mePartnerOffersLoader).toHaveBeenCalledWith({ + artwork_id: "richard-prince-untitled-portrait", + size: 1, + sort: "-created_at", }) - it("only returns active partner offer signal", async () => { - mockIsFeatureFlagEnabled.mockReturnValue(true) + expect(data.artwork.collectorSignals.partnerOffer).toEqual({ + endAt: "2023-01-01T00:00:00Z", + }) + }) - artwork.purchasable = true - artwork.sale_ids = [] + it("only returns active partner offer signal", async () => { + artwork.purchasable = true + artwork.sale_ids = [] - context.userID = "user-id" - context.mePartnerOffersLoader.mockResolvedValue({ - body: [{ endAt: "2023-01-01T00:00:00Z", active: false }], - }) + context.userID = "user-id" + context.mePartnerOffersLoader.mockResolvedValue({ + body: [{ endAt: "2023-01-01T00:00:00Z", active: false }], + }) - const data = await runQuery(query, context) + const data = await runQuery(query, context) - expect(data.artwork.collectorSignals.partnerOffer).toBeNull() - }) + expect(data.artwork.collectorSignals.partnerOffer).toBeNull() + }) - it("does not query partner offer signal loaders if the user is not logged in", async () => { - context.mePartnerOffersLoader = null + it("does not query partner offer signal loaders if the user is not logged in", async () => { + context.mePartnerOffersLoader = null - const data = await runQuery(query, context) + const data = await runQuery(query, context) - expect(data).toEqual({ - artwork: { - collectorSignals: expect.objectContaining({ - partnerOffer: null, - }), - }, - }) + expect(data).toEqual({ + artwork: { + collectorSignals: expect.objectContaining({ + partnerOffer: null, + }), + }, }) - describe("primaryLabel signal", () => { - const query = ` - { - artwork(id: "richard-prince-untitled-portrait") { - collectorSignals { - primaryLabel - } + }) + + describe("primaryLabel signal", () => { + const query = ` + { + artwork(id: "richard-prince-untitled-portrait") { + collectorSignals { + primaryLabel } } - ` - it("'PARTNER_OFFER' takes precedence over 'INCREASED_INTEREST' and 'CURATORS_PICK' unless ignored", async () => { - context.mePartnerOffersLoader.mockResolvedValue({ - body: [{ endAt: "2023-01-01", active: true }], - }) - context.marketingCollectionLoader.mockResolvedValue({ - artwork_ids: [artwork._id], - }) - artwork.increased_interest_signal = true - - const data = await runQuery(query, context) - expect(data.artwork.collectorSignals.primaryLabel).toEqual( - "PARTNER_OFFER" - ) + } + ` + it("does not include 'PARTNER_OFFER'", async () => { + context.mePartnerOffersLoader.mockResolvedValue({ + body: [{ endAt: "2023-01-01", active: true }], }) - it("CURATORS_PICK takes precedence over INCREASED_INTEREST", async () => { - context.mePartnerOffersLoader.mockResolvedValue({ - body: [], - }) - context.marketingCollectionLoader.mockResolvedValue({ - artwork_ids: [artwork._id], - }) - artwork.increased_interest_signal = true + const data = await runQuery(query, context) + expect(data.artwork.collectorSignals.primaryLabel).toBeNull() + }) - const data = await runQuery(query, context) - expect(data.artwork.collectorSignals.primaryLabel).toEqual( - "CURATORS_PICK" - ) + it("CURATORS_PICK takes precedence over INCREASED_INTEREST", async () => { + context.mePartnerOffersLoader.mockResolvedValue({ + body: [], }) - - it("shows 'INCREASED_INTEREST' if artwork.increased_interest_signal is present and no other labels are available", async () => { - context.mePartnerOffersLoader.mockResolvedValue({ - body: [], - }) - context.marketingCollectionLoader.mockResolvedValue({ - artwork_ids: ["not-this-artwork"], - }) - artwork.increased_interest_signal = true - const data = await runQuery(query, context) - expect(data.artwork.collectorSignals.primaryLabel).toEqual( - "INCREASED_INTEREST" - ) + context.marketingCollectionLoader.mockResolvedValue({ + artwork_ids: [artwork._id], }) + artwork.increased_interest_signal = true - it("primaryLabel choices can be suppressed through `ignorePrimaryLabels` arg", async () => { - context.mePartnerOffersLoader.mockResolvedValue({ - body: [{ endAt: "2023-01-01", active: true }], - }) - context.marketingCollectionLoader.mockResolvedValue({ - artwork_ids: [artwork._id], - }) - artwork.increased_interest_signal = true - - const data = await runQuery(query, context) - expect(data.artwork.collectorSignals.primaryLabel).toEqual( - "PARTNER_OFFER" - ) + const data = await runQuery(query, context) + expect(data.artwork.collectorSignals.primaryLabel).toEqual( + "CURATORS_PICK" + ) + }) - const queryWithoutPartnerOffer = ` - { - artwork(id: "richard-prince-untitled-portrait") { - collectorSignals { - primaryLabel(ignore: [PARTNER_OFFER]) - } - } - } - ` - const dataWithoutPartnerOffer = await runQuery( - queryWithoutPartnerOffer, - context - ) + it("shows 'INCREASED_INTEREST' if artwork.increased_interest_signal is present and no other labels are available", async () => { + context.mePartnerOffersLoader.mockResolvedValue({ + body: [], + }) + context.marketingCollectionLoader.mockResolvedValue({ + artwork_ids: ["not-this-artwork"], + }) + artwork.increased_interest_signal = true + const data = await runQuery(query, context) + expect(data.artwork.collectorSignals.primaryLabel).toEqual( + "INCREASED_INTEREST" + ) + }) - expect( - dataWithoutPartnerOffer.artwork.collectorSignals.primaryLabel - ).toEqual("CURATORS_PICK") + it("primaryLabel choices can be suppressed through `ignorePrimaryLabels` arg", async () => { + context.mePartnerOffersLoader.mockResolvedValue({ + body: [{ endAt: "2023-01-01", active: true }], + }) + context.marketingCollectionLoader.mockResolvedValue({ + artwork_ids: [artwork._id], + }) + artwork.increased_interest_signal = true - const queryWithoutPartnerOfferAndCuratorsPick = ` - { - artwork(id: "richard-prince-untitled-portrait") { - collectorSignals { - primaryLabel(ignore: [PARTNER_OFFER, CURATORS_PICK]) - } - } - } - ` - const dataWithoutPartnerOfferAndCuratorsPick = await runQuery( - queryWithoutPartnerOfferAndCuratorsPick, - context - ) - expect( - dataWithoutPartnerOfferAndCuratorsPick.artwork.collectorSignals - .primaryLabel - ).toEqual("INCREASED_INTEREST") + const data = await runQuery(query, context) + expect(data.artwork.collectorSignals.primaryLabel).toEqual( + "CURATORS_PICK" + ) - const queryWithAllLabelsExcluded = ` + const queryWithoutPartnerOffer = ` { artwork(id: "richard-prince-untitled-portrait") { collectorSignals { - primaryLabel(ignore: [PARTNER_OFFER, CURATORS_PICK, INCREASED_INTEREST]) + primaryLabel(ignore: [CURATORS_PICK]) } } } ` - const dataWithAllLabelsExcluded = await runQuery( - queryWithAllLabelsExcluded, - context - ) - expect( - dataWithAllLabelsExcluded.artwork.collectorSignals.primaryLabel - ).toBeNull() - }) + const dataWithoutPartnerOffer = await runQuery( + queryWithoutPartnerOffer, + context + ) + + expect( + dataWithoutPartnerOffer.artwork.collectorSignals.primaryLabel + ).toEqual("INCREASED_INTEREST") - it("does not allow illegal values for `ignorePrimaryLabels` arg", async () => { - const queryWithTooManyLabels = ` + const queryWithoutPartnerOfferAndCuratorsPick = ` { artwork(id: "richard-prince-untitled-portrait") { collectorSignals { - primaryLabel(ignore: [PARTNER_OFFER, CURATORS_PICK, INCREASED_INTEREST, PARTNER_OFFER]) + primaryLabel(ignore: [CURATORS_PICK, INCREASED_INTEREST]) } } } ` - await expect( - runQuery(queryWithTooManyLabels, context) - ).rejects.toThrow( - new Error( - `Ignore list length limited to number of available signals - max 3` - ) - ) - }) - - it("returns null if there is no active partner offer increased interest, or curators pick collection", async () => { - context.mePartnerOffersLoader.mockResolvedValue({ - body: [], - }) - artwork.increased_interest_signal = false - const data = await runQuery(query, context) - expect(data.artwork.collectorSignals.primaryLabel).toBeNull() - }) + const dataWithoutPartnerOfferAndCuratorsPick = await runQuery( + queryWithoutPartnerOfferAndCuratorsPick, + context + ) + expect( + dataWithoutPartnerOfferAndCuratorsPick.artwork.collectorSignals + .primaryLabel + ).toBeNull() }) - }) - describe("auction artwork", () => { - beforeEach(() => { - artwork.purchasable = false - artwork.sale_ids = ["sale-id-not-auction", "sale-id-auction"] + it("does not allow illegal values for `ignorePrimaryLabels` arg", async () => { + const queryWithTooManyLabels = ` + { + artwork(id: "richard-prince-untitled-portrait") { + collectorSignals { + primaryLabel(ignore: [PARTNER_OFFER, CURATORS_PICK, INCREASED_INTEREST, PARTNER_OFFER]) + } + } + } + ` + await expect( + runQuery(queryWithTooManyLabels, context) + ).rejects.toThrow( + new Error( + `Ignore list length limited to number of available signals - max 3` + ) + ) }) - const futureTime = moment().add(1, "day").toISOString() - const pastTime = moment().subtract(1, "day").toISOString() - - it("returns null for primaryLabel even if a signal is available", async () => { - artwork.increased_interest_signal = true + it("returns null if there is no active partner offer increased interest, or curators pick collection", async () => { + context.mePartnerOffersLoader.mockResolvedValue({ + body: [], + }) + artwork.increased_interest_signal = false const data = await runQuery(query, context) expect(data.artwork.collectorSignals.primaryLabel).toBeNull() }) + }) + }) - it("returns false for increasedInterest", async () => { - artwork.increased_interest_signal = true + describe("auction artwork", () => { + beforeEach(() => { + artwork.purchasable = false + artwork.sale_ids = ["sale-id-not-auction", "sale-id-auction"] + }) - const data = await runQuery(query, context) + const futureTime = moment().add(1, "day").toISOString() + const pastTime = moment().subtract(1, "day").toISOString() - expect(data.artwork.collectorSignals.increasedInterest).toEqual(false) - }) - it("returns the nested registration end time if present, whether future or past", async () => { - context.salesLoader.mockResolvedValue([ - { id: "sale-id-auction", registration_ends_at: futureTime }, - ]) + it("returns null for primaryLabel even if a signal is available", async () => { + artwork.increased_interest_signal = true + const data = await runQuery(query, context) + expect(data.artwork.collectorSignals.primaryLabel).toBeNull() + }) - context.saleArtworkLoader.mockResolvedValue({}) + it("returns false for increasedInterest", async () => { + artwork.increased_interest_signal = true - let data = await runQuery(query, context) + const data = await runQuery(query, context) - expect( - data.artwork.collectorSignals.auction.registrationEndsAt - ).toEqual(futureTime) + expect(data.artwork.collectorSignals.increasedInterest).toEqual(false) + }) + it("returns the nested registration end time if present, whether future or past", async () => { + context.salesLoader.mockResolvedValue([ + { id: "sale-id-auction", registration_ends_at: futureTime }, + ]) - context.salesLoader.mockResolvedValue([ - { id: "sale-id-auction", registration_ends_at: pastTime }, - ]) - context.saleArtworkLoader.mockResolvedValue({}) + context.saleArtworkLoader.mockResolvedValue({}) - data = await runQuery(query, context) + let data = await runQuery(query, context) - expect( - data.artwork.collectorSignals.auction.registrationEndsAt - ).toEqual(pastTime) - }) + expect( + data.artwork.collectorSignals.auction.registrationEndsAt + ).toEqual(futureTime) - it("returns correct nested values for a lot with an end time and no extended bidding", async () => { - context.salesLoader.mockResolvedValue([{ id: "sale-id-auction" }]) + context.salesLoader.mockResolvedValue([ + { id: "sale-id-auction", registration_ends_at: pastTime }, + ]) + context.saleArtworkLoader.mockResolvedValue({}) - context.saleArtworkLoader.mockResolvedValue({ - end_at: futureTime, - extended_bidding_end_at: null, - }) + data = await runQuery(query, context) - const data = await runQuery(query, context) + expect( + data.artwork.collectorSignals.auction.registrationEndsAt + ).toEqual(pastTime) + }) - expect(data.artwork.collectorSignals.auction.lotClosesAt).toEqual( - futureTime - ) - expect( - data.artwork.collectorSignals.auction.onlineBiddingExtended - ).toEqual(false) + it("returns correct nested values for a lot with an end time and no extended bidding", async () => { + context.salesLoader.mockResolvedValue([{ id: "sale-id-auction" }]) + + context.saleArtworkLoader.mockResolvedValue({ + end_at: futureTime, + extended_bidding_end_at: null, }) - it("returns correct nested values for a lot with an end time and extended bidding", async () => { - context.salesLoader.mockResolvedValue([{ id: "sale-id-auction" }]) + const data = await runQuery(query, context) - context.saleArtworkLoader.mockResolvedValue({ - end_at: pastTime, - extended_bidding_end_at: futureTime, - }) + expect(data.artwork.collectorSignals.auction.lotClosesAt).toEqual( + futureTime + ) + expect( + data.artwork.collectorSignals.auction.onlineBiddingExtended + ).toEqual(false) + }) - const data = await runQuery(query, context) + it("returns correct nested values for a lot with an end time and extended bidding", async () => { + context.salesLoader.mockResolvedValue([{ id: "sale-id-auction" }]) - expect(data.artwork.collectorSignals.auction.lotClosesAt).toEqual( - futureTime - ) - expect( - data.artwork.collectorSignals.auction.onlineBiddingExtended - ).toEqual(true) + context.saleArtworkLoader.mockResolvedValue({ + end_at: pastTime, + extended_bidding_end_at: futureTime, }) - it("returns correct nested values for a lot with a future live start time", async () => { - context.salesLoader.mockResolvedValue([ - { id: "sale-id-auction", live_start_at: futureTime }, - ]) - // live start at not set on sale artwork - context.saleArtworkLoader.mockResolvedValue({}) - const data = await runQuery(query, context) + const data = await runQuery(query, context) - expect( - data.artwork.collectorSignals.auction.liveBiddingStarted - ).toEqual(false) - expect(data.artwork.collectorSignals.auction.lotClosesAt).toEqual( - null - ) - expect(data.artwork.collectorSignals.auction.liveStartAt).toEqual( - futureTime - ) - }) - it("returns correct nested values for an auction that has started live bidding", async () => { - context.salesLoader.mockResolvedValue([ - { - id: "sale-id-auction", - live_start_at: pastTime, - live_integration_started: true, - }, - ]) + expect(data.artwork.collectorSignals.auction.lotClosesAt).toEqual( + futureTime + ) + expect( + data.artwork.collectorSignals.auction.onlineBiddingExtended + ).toEqual(true) + }) + it("returns correct nested values for a lot with a future live start time", async () => { + context.salesLoader.mockResolvedValue([ + { id: "sale-id-auction", live_start_at: futureTime }, + ]) - // live start at not set on sale artwork - context.saleArtworkLoader.mockResolvedValue({}) - const data = await runQuery(query, context) + // live start at not set on sale artwork + context.saleArtworkLoader.mockResolvedValue({}) + const data = await runQuery(query, context) - expect( - data.artwork.collectorSignals.auction.liveBiddingStarted - ).toEqual(true) + expect( + data.artwork.collectorSignals.auction.liveBiddingStarted + ).toEqual(false) + expect(data.artwork.collectorSignals.auction.lotClosesAt).toEqual(null) + expect(data.artwork.collectorSignals.auction.liveStartAt).toEqual( + futureTime + ) + }) + it("returns correct nested values for an auction that has started live bidding", async () => { + context.salesLoader.mockResolvedValue([ + { + id: "sale-id-auction", + live_start_at: pastTime, + live_integration_started: true, + }, + ]) - expect(data.artwork.collectorSignals.auction.liveStartAt).toEqual( - pastTime - ) - }) + // live start at not set on sale artwork + context.saleArtworkLoader.mockResolvedValue({}) + const data = await runQuery(query, context) - it("fetches & returns the nested lot watcher and bid count signals for an auction lot artwork if requested", async () => { - artwork.recent_saves_count = 123 - context.salesLoader.mockResolvedValue([ - { - id: "sale-id-auction", - _id: "sale-database-id", - }, - ]) + expect( + data.artwork.collectorSignals.auction.liveBiddingStarted + ).toEqual(true) - context.saleArtworkLoader.mockResolvedValue({ - bidder_positions_count: 5, - }) + expect(data.artwork.collectorSignals.auction.liveStartAt).toEqual( + pastTime + ) + }) - const data = await runQuery(query, context) + it("fetches & returns the nested lot watcher and bid count signals for an auction lot artwork if requested", async () => { + artwork.recent_saves_count = 123 + context.salesLoader.mockResolvedValue([ + { + id: "sale-id-auction", + _id: "sale-database-id", + }, + ]) - expect(context.salesLoader).toHaveBeenCalledWith({ - id: ["sale-id-not-auction", "sale-id-auction"], - is_auction: true, - live: true, - }) + context.saleArtworkLoader.mockResolvedValue({ + bidder_positions_count: 5, + }) - expect(context.saleArtworkLoader).toHaveBeenCalledWith({ - artworkId: "richard-prince-untitled-portrait-database-id", - saleId: "sale-database-id", - }) + const data = await runQuery(query, context) - expect(data.artwork.collectorSignals.auction.bidCount).toEqual(5) - expect(data.artwork.collectorSignals.auction.lotWatcherCount).toEqual( - 123 - ) + expect(context.salesLoader).toHaveBeenCalledWith({ + id: ["sale-id-not-auction", "sale-id-auction"], + is_auction: true, + live: true, }) - it("does not query auction signal loaders if the artwork has no sale_ids", async () => { - artwork.sale_ids = [] - artwork.purchasable = true + expect(context.saleArtworkLoader).toHaveBeenCalledWith({ + artworkId: "richard-prince-untitled-portrait-database-id", + saleId: "sale-database-id", + }) - const data = await runQuery(query, context) + expect(data.artwork.collectorSignals.auction.bidCount).toEqual(5) + expect(data.artwork.collectorSignals.auction.lotWatcherCount).toEqual( + 123 + ) + }) - expect(context.salesLoader).not.toHaveBeenCalled() - expect(context.saleArtworkLoader).not.toHaveBeenCalled() + it("does not query auction signal loaders if the artwork has no sale_ids", async () => { + artwork.sale_ids = [] + artwork.purchasable = true - expect(data.artwork.collectorSignals.auction).toBeNull() - }) + const data = await runQuery(query, context) - it("may return auction data after end time if the sale closes late", async () => { - artwork.purchasable = true - context.salesLoader.mockResolvedValue([ - { id: "sale-id-auction", end_at: pastTime, ended_at: null }, - ]) - context.saleArtworkLoader.mockResolvedValue({ - end_at: pastTime, - extended_bidding_end_at: pastTime, - }) + expect(context.salesLoader).not.toHaveBeenCalled() + expect(context.saleArtworkLoader).not.toHaveBeenCalled() - const data = await runQuery(query, context) + expect(data.artwork.collectorSignals.auction).toBeNull() + }) - expect(data.artwork.collectorSignals.auction.lotClosesAt).toEqual( - pastTime - ) + it("may return auction data after end time if the sale closes late", async () => { + artwork.purchasable = true + context.salesLoader.mockResolvedValue([ + { id: "sale-id-auction", end_at: pastTime, ended_at: null }, + ]) + context.saleArtworkLoader.mockResolvedValue({ + end_at: pastTime, + extended_bidding_end_at: pastTime, }) - }) - describe("curatorsPick", () => { - it("returns true if the artwork id is in a curated collection but has sale_ids", async () => { - artwork.purchasable = true - artwork.sale_ids = ["sale-id-auction"] - context.marketingCollectionLoader.mockResolvedValue({ - artwork_ids: [artwork._id], - }) + const data = await runQuery(query, context) - const data = await runQuery(query, context) - expect(data.artwork.collectorSignals.curatorsPick).toBe(true) + expect(data.artwork.collectorSignals.auction.lotClosesAt).toEqual( + pastTime + ) + }) + }) + + describe("curatorsPick", () => { + it("returns true if the artwork id is in a curated collection but has sale_ids", async () => { + artwork.purchasable = true + artwork.sale_ids = ["sale-id-auction"] + context.marketingCollectionLoader.mockResolvedValue({ + artwork_ids: [artwork._id], }) - it("returns true if the artwork id is in a curated collection with no sale ids", async () => { - artwork.purchasable = true - artwork.sale_ids = [] - context.marketingCollectionLoader.mockResolvedValue({ - artwork_ids: [artwork._id], - }) + const data = await runQuery(query, context) + expect(data.artwork.collectorSignals.curatorsPick).toBe(true) + }) - const data = await runQuery(query, context) - expect(data.artwork.collectorSignals.curatorsPick).toBe(true) + it("returns true if the artwork id is in a curated collection with no sale ids", async () => { + artwork.purchasable = true + artwork.sale_ids = [] + context.marketingCollectionLoader.mockResolvedValue({ + artwork_ids: [artwork._id], }) - it("returns false if the artwork id is not in a curated collection", async () => { - artwork.purchasable = true - context.marketingCollectionLoader.mockResolvedValue({ - artwork_ids: [], - }) + const data = await runQuery(query, context) + expect(data.artwork.collectorSignals.curatorsPick).toBe(true) + }) - const data = await runQuery(query, context) - expect(data.artwork.collectorSignals.curatorsPick).toBe(false) + it("returns false if the artwork id is not in a curated collection", async () => { + artwork.purchasable = true + context.marketingCollectionLoader.mockResolvedValue({ + artwork_ids: [], }) - }) - describe("runningShow", () => { - it("returns the show or fair if the artwork id is in a running show or fair", async () => { - artwork.purchasable = true - context.relatedShowsLoader.mockResolvedValue({ - body: [ - { - name: "Test Show", - start_at: "2023-01-01T00:00:00Z", - end_at: "2023-01-02T00:00:00Z", - }, - ], - }) + const data = await runQuery(query, context) + expect(data.artwork.collectorSignals.curatorsPick).toBe(false) + }) + }) - const data = await runQuery(query, context) - expect(data.artwork.collectorSignals.runningShow).toEqual({ - name: "Test Show", - startAt: "2023-01-01T00:00:00Z", - endAt: "2023-01-02T00:00:00Z", - }) + describe("runningShow", () => { + it("returns the show or fair if the artwork id is in a running show or fair", async () => { + artwork.purchasable = true + context.relatedShowsLoader.mockResolvedValue({ + body: [ + { + name: "Test Show", + start_at: "2023-01-01T00:00:00Z", + end_at: "2023-01-02T00:00:00Z", + }, + ], }) - it("returns null if the artwork id is not in a running show or fair", async () => { - artwork.purchasable = true - context.relatedShowsLoader.mockResolvedValue({ body: [] }) - - const data = await runQuery(query, context) - expect(data.artwork.collectorSignals.runningShow).toBeNull() + const data = await runQuery(query, context) + expect(data.artwork.collectorSignals.runningShow).toEqual({ + name: "Test Show", + startAt: "2023-01-01T00:00:00Z", + endAt: "2023-01-02T00:00:00Z", }) }) - it("is null if the artwork has never been in auction and is not purchasable", async () => { - artwork.purchasable = false - artwork.sale_ids = [] + it("returns null if the artwork id is not in a running show or fair", async () => { + artwork.purchasable = true + context.relatedShowsLoader.mockResolvedValue({ body: [] }) const data = await runQuery(query, context) - - expect(context.mePartnerOffersLoader).not.toHaveBeenCalled() - - expect(data.artwork.collectorSignals).toBeNull() + expect(data.artwork.collectorSignals.runningShow).toBeNull() }) + }) - it("does not query partner offer signal loaders if the artwork is not purchasable", async () => { - artwork.purchasable = false + it("is null if the artwork has never been in auction and is not purchasable", async () => { + artwork.purchasable = false + artwork.sale_ids = [] - const data = await runQuery(query, context) + const data = await runQuery(query, context) - expect(context.mePartnerOffersLoader).not.toHaveBeenCalled() + expect(context.mePartnerOffersLoader).not.toHaveBeenCalled() - expect(data.artwork.collectorSignals.partnerOffer).toBeNull() - }) - - it("does not query partner offer signal loaders if the partnerOffer field is not requested", async () => { - context.salesLoader.mockResolvedValue([]) + expect(data.artwork.collectorSignals).toBeNull() + }) - const noPartnerOfferQuery = ` + it("does not query partner offer signal loaders if the artwork is not purchasable", async () => { + artwork.purchasable = false - { - artwork(id: "richard-prince-untitled-portrait") { - collectorSignals { - increasedInterest - } - } - }` + const data = await runQuery(query, context) - const data = await runQuery(noPartnerOfferQuery, context) + expect(context.mePartnerOffersLoader).not.toHaveBeenCalled() - expect(context.mePartnerOffersLoader).not.toHaveBeenCalled() + expect(data.artwork.collectorSignals.partnerOffer).toBeNull() + }) - expect(data).toEqual({ - artwork: { - collectorSignals: { - increasedInterest: false, - }, - }, - }) - }) + it("does not query partner offer signal loaders if the partnerOffer field is not requested", async () => { + context.salesLoader.mockResolvedValue([]) - it("does not query auction loaders if the auction field is not requested", async () => { - const noAuctionFieldsQuery = ` + const noPartnerOfferQuery = ` { artwork(id: "richard-prince-untitled-portrait") { collectorSignals { - partnerOffer { endAt } + increasedInterest } } }` - const data = await runQuery(noAuctionFieldsQuery, context) + const data = await runQuery(noPartnerOfferQuery, context) - expect(context.salesLoader).not.toHaveBeenCalled() + expect(context.mePartnerOffersLoader).not.toHaveBeenCalled() - expect(data).toEqual({ - artwork: { - collectorSignals: { - partnerOffer: null, - }, + expect(data).toEqual({ + artwork: { + collectorSignals: { + increasedInterest: false, }, - }) + }, + }) + }) + + it("does not query auction loaders if the auction field is not requested", async () => { + const noAuctionFieldsQuery = ` + + { + artwork(id: "richard-prince-untitled-portrait") { + collectorSignals { + partnerOffer { endAt } + } + } + }` + + const data = await runQuery(noAuctionFieldsQuery, context) + + expect(context.salesLoader).not.toHaveBeenCalled() + + expect(data).toEqual({ + artwork: { + collectorSignals: { + partnerOffer: null, + }, + }, }) }) }) diff --git a/src/schema/v2/artwork/collectorSignals.ts b/src/schema/v2/artwork/collectorSignals.ts index 2798ea38bd..f6821ea889 100644 --- a/src/schema/v2/artwork/collectorSignals.ts +++ b/src/schema/v2/artwork/collectorSignals.ts @@ -200,7 +200,7 @@ export const CollectorSignals: GraphQLFieldConfig = { }), } -type PrimaryLabel = "PARTNER_OFFER" | "INCREASED_INTEREST" | "CURATORS_PICK" +type PrimaryLabel = "INCREASED_INTEREST" | "CURATORS_PICK" // Single function to resolve mutually-exclusive label signals const getPrimaryLabel = async ( @@ -213,23 +213,13 @@ const getPrimaryLabel = async ( } const ignoreLabels = args.ignore - const partnerOfferPromise = - !ignoreLabels?.includes("PARTNER_OFFER") && - getActivePartnerOffer(artwork, ctx) const curatorsPickPromise = !ignoreLabels?.includes("CURATORS_PICK") && getIsCuratorsPick(artwork, ctx) const increasedInterest = !ignoreLabels?.includes("INCREASED_INTEREST") && getIncreasedInterest(artwork) - const [activePartnerOffer, curatorsPick] = await Promise.all([ - partnerOfferPromise, - curatorsPickPromise, - ]) - - if (activePartnerOffer) { - return "PARTNER_OFFER" - } + const [curatorsPick] = await Promise.all([curatorsPickPromise]) if (curatorsPick) { return "CURATORS_PICK"