From 8088b563b00842c02e722eefd8c7fb166c5c333c Mon Sep 17 00:00:00 2001 From: Tim Hostetler <6970899+thostetler@users.noreply.github.com> Date: Wed, 30 Sep 2026 13:57:32 -0400 Subject: [PATCH] fix(facets): limit Collections facet to classic ADS databases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Collections facet now lists only astronomy, physics, and general; SciX subcategories (astrophysics, planetary, heliophysics, earthscience) no longer appear. A query already filtered to a hidden collection still runs unchanged — only the facet checkbox list is filtered. --- src/js/wraps/database_facet.js | 9 ++ test/mocha/js/wraps/database_facet.spec.js | 144 +++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 test/mocha/js/wraps/database_facet.spec.js diff --git a/src/js/wraps/database_facet.js b/src/js/wraps/database_facet.js index 49ba45ac0..c3221a160 100644 --- a/src/js/wraps/database_facet.js +++ b/src/js/wraps/database_facet.js @@ -1,9 +1,18 @@ define(['js/widgets/facet/factory'], function(FacetFactory) { + var ALLOWED_COLLECTIONS = ['astronomy', 'physics', 'general']; + return function() { var widget = FacetFactory.makeBasicCheckboxFacet({ facetField: 'database', facetTitle: 'Collections', openByDefault: true, + + preprocessors: function(facetList) { + return facetList.filter(function(f) { + return _.indexOf(ALLOWED_COLLECTIONS, f.value) !== -1; + }); + }, + logicOptions: { single: ['limit to', 'exclude'], multiple: ['and', 'or', 'exclude'], diff --git a/test/mocha/js/wraps/database_facet.spec.js b/test/mocha/js/wraps/database_facet.spec.js new file mode 100644 index 000000000..d4af90cd5 --- /dev/null +++ b/test/mocha/js/wraps/database_facet.spec.js @@ -0,0 +1,144 @@ +define(['underscore', 'js/components/api_query', 'js/widgets/facet/actions', 'js/wraps/database_facet'], function( + _, + ApiQuery, + Actions, + DatabaseFacet +) { + describe('Database (Collections) Facet (database_facet.spec.js)', function() { + var makeResponse = function(facetFields, facetLimit) { + return { + responseHeader: { + status: 0, + QTime: 4, + params: { + 'facet.limit': facetLimit || '20', + q: 'star', + 'facet.field': 'database', + 'facet.offset': '0', + 'facet.mincount': '1', + facet: 'true', + wt: 'json', + }, + }, + response: { numFound: 10, start: 0, docs: [] }, + facet_counts: { + facet_queries: {}, + facet_fields: { database: facetFields }, + facet_dates: {}, + facet_ranges: {}, + }, + }; + }; + + var fullFacetFields = [ + 'astronomy', + 5000, + 'astrophysics', + 4800, + 'physics', + 1200, + 'planetary', + 900, + 'heliophysics', + 700, + 'general', + 300, + 'earthscience', + 100, + ]; + + var getPreprocessors = function(widget) { + var preprocessors = widget.store.getState().config.preprocessors; + return _.isFunction(preprocessors) ? [preprocessors] : preprocessors; + }; + + var runPreprocessors = function(widget, facetList) { + return _.reduce( + getPreprocessors(widget), + function(list, fn) { + return fn(list); + }, + facetList + ); + }; + + it('shows only the classic ADS collections', function() { + var widget = DatabaseFacet(); + widget.store.dispatch(Actions().data_received(makeResponse(fullFacetFields))); + + expect(widget.store.getState().children).to.eql(['astronomy', 'physics', 'general']); + }); + + it('drops SciX collections from the rendered facet list', function() { + var widget = DatabaseFacet(); + widget.store.dispatch(Actions().data_received(makeResponse(fullFacetFields))); + + var state = widget.store.getState(); + _.each(['astrophysics', 'planetary', 'heliophysics', 'earthscience'], function(value) { + expect(state.facets[value]).to.equal(undefined); + }); + }); + + it('preserves the counts of the collections it keeps', function() { + var widget = DatabaseFacet(); + widget.store.dispatch(Actions().data_received(makeResponse(fullFacetFields))); + + var facets = widget.store.getState().facets; + expect(facets.astronomy.count).to.eql(5000); + expect(facets.physics.count).to.eql(1200); + expect(facets.general.count).to.eql(300); + }); + + it('is an allowlist, so an unknown collection is not shown', function() { + var widget = DatabaseFacet(); + var filtered = runPreprocessors(widget, [ + { value: 'astronomy', name: 'astronomy', count: 1 }, + { value: 'brand_new_scix_collection', name: 'brand_new_scix_collection', count: 1 }, + ]); + + expect(_.pluck(filtered, 'value')).to.eql(['astronomy']); + }); + + it('handles an empty facet list', function() { + var widget = DatabaseFacet(); + expect(runPreprocessors(widget, [])).to.eql([]); + }); + + it('marks pagination finished so the "more" button stays hidden', function() { + var widget = DatabaseFacet(); + widget.store.dispatch(Actions().data_received(makeResponse(fullFacetFields, '20'))); + + expect(widget.store.getState().pagination.finished).to.eql(true); + }); + + it('leaves a filter on a hidden collection untouched in the outgoing query', function() { + var widget = DatabaseFacet(); + var query = new ApiQuery({ + q: 'star', + fq: ['{!type=aqp v=$fq_database}'], + fq_database: ['(database:astrophysics OR database:planetary)'], + }); + + widget.store.dispatch(Actions().data_received(makeResponse(fullFacetFields))); + var outgoing = widget.customizeQuery(query); + + expect(outgoing.get('fq')).to.eql(['{!type=aqp v=$fq_database}']); + expect(outgoing.get('fq_database')).to.eql(['(database:astrophysics OR database:planetary)']); + expect(outgoing.get('q')).to.eql(['star']); + }); + + it('computes pagination.finished from the raw bucket count, not the filtered list', function() { + var widget = DatabaseFacet(); + var fullPage = []; + _.times(20, function(i) { + fullPage.push(i === 0 ? 'astronomy' : 'scix_collection_' + i, 100 - i); + }); + + widget.store.dispatch(Actions().data_received(makeResponse(fullPage, '20'))); + + var state = widget.store.getState(); + expect(state.children).to.eql(['astronomy']); + expect(state.pagination.finished).to.eql(false); + }); + }); +});