diff --git a/src/handlers/get-collection-by-id.js b/src/handlers/get-collection-by-id.js index 4c8f4f52..f9e73aea 100644 --- a/src/handlers/get-collection-by-id.js +++ b/src/handlers/get-collection-by-id.js @@ -4,15 +4,24 @@ const { getCollection } = require("../api/opensearch"); const { wrap } = require("./middleware"); const opensearchResponse = require("../api/response/opensearch"); +const getOpts = (event) => { + const id = event.pathParameters.id; + + const allowPrivate = + event.userToken.isReadingRoom() || event.userToken.hasEntitlement(id); + const allowUnpublished = event.userToken.hasEntitlement(id); + return { allowPrivate, allowUnpublished }; +}; + const getCollectionById = async (event) => { const id = event.pathParameters.id; - const esResponse = await getCollection(id); + const esResponse = await getCollection(id, getOpts(event)); return await opensearchResponse.transform(esResponse); }; const getIiifCollectionById = async (event) => { const id = event.pathParameters.id; - const esResponse = await getCollection(id); + const esResponse = await getCollection(id, getOpts(event)); const collection = JSON.parse(esResponse.body)?._source; if (!collection) return { statusCode: 404, body: "Not Found" }; const parameterOverrides = { ...event.queryStringParameters }; diff --git a/test/fixtures/mocks/collection-1234-private-published.json b/test/fixtures/mocks/collection-1234-private-published.json new file mode 100644 index 00000000..cdfa4812 --- /dev/null +++ b/test/fixtures/mocks/collection-1234-private-published.json @@ -0,0 +1,17 @@ +{ + "_index": "dev-dc-v2-collection", + "_type": "_doc", + "_id": "1234", + "_version": 1, + "found": true, + "_source": { + "id": "1234", + "title": "Collection Title", + "api_model": "Collection", + "published": true, + "visibility": "Private", + "representative_image": { + "work_id": "1234" + } + } +} \ No newline at end of file diff --git a/test/integration/get-collection-by-id.test.js b/test/integration/get-collection-by-id.test.js index 62f8e300..e05e444d 100644 --- a/test/integration/get-collection-by-id.test.js +++ b/test/integration/get-collection-by-id.test.js @@ -11,6 +11,10 @@ describe("Retrieve collection by id", () => { const mock = helpers.mockIndex(); describe("GET /collections/{id}", () => { + beforeEach(() => { + process.env.READING_ROOM_IPS = ""; + }); + const { handler } = requireSource("handlers/get-collection-by-id"); it("retrieves a single collection link document", async () => { @@ -46,6 +50,41 @@ describe("Retrieve collection by id", () => { expect(result.statusCode).to.eq(404); }); + it("404's if the collection is private", async () => { + mock + .get("/dc-v2-collection/_doc/1234") + .reply( + 200, + helpers.testFixture("mocks/collection-1234-private-published.json") + ); + + const event = helpers + .mockEvent("GET", "/collections/{id}") + .pathParams({ id: 1234 }) + .render(); + + const result = await handler(event); + expect(result.statusCode).to.eq(404); + }); + + it("200's if the collection is private but the user is in the reading room", async () => { + mock + .get("/dc-v2-collection/_doc/1234") + .reply( + 200, + helpers.testFixture("mocks/collection-1234-private-published.json") + ); + + const event = helpers + .mockEvent("GET", "/collections/{id}") + .pathParams({ id: 1234 }) + .render(); + + process.env.READING_ROOM_IPS = event.requestContext.http.sourceIp; + const result = await handler(event); + expect(result.statusCode).to.eq(200); + }); + it("returns a single collection as a IIIF collection", async () => { const originalQuery = { query: { query_string: { query: "collection.id:1234" } }, @@ -90,5 +129,42 @@ describe("Retrieve collection by id", () => { "https://api.test.library.northwestern.edu/api/v2/collections" ); }); + + it("returns a IIIF collection if the user is in the reading room", async () => { + const originalQuery = { + query: { query_string: { query: "collection.id:1234" } }, + }; + const authQuery = new RequestPipeline(originalQuery) + .authFilter(helpers.preprocess({})) + .toJson(); + + mock + .get("/dc-v2-collection/_doc/1234") + .reply( + 200, + helpers.testFixture("mocks/collection-1234-private-published.json") + ); + mock + .post("/dc-v2-work/_search", authQuery) + .reply(200, helpers.testFixture("mocks/search.json")); + + const event = helpers + .mockEvent("GET", "/collections/{id}") + .pathParams({ id: 1234 }) + .queryParams({ as: "iiif" }) + .render(); + + process.env.READING_ROOM_IPS = event.requestContext.http.sourceIp; + + const result = await handler(event); + expect(result.statusCode).to.eq(200); + expect(result).to.have.header( + "content-type", + /application\/json;.*charset=UTF-8/ + ); + const resultBody = JSON.parse(result.body); + expect(resultBody.type).to.eq("Collection"); + expect(resultBody.label.none[0]).to.eq("Collection Title"); + }); }); });