Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 46 additions & 3 deletions lib/test_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,22 @@ testHelper.deleteIndices = async ( ) => {
await testHelper.forEachIndex( esClient.deleteIndex );
};

testHelper.insertIntoIndex = async ( index, type, statements ) => {
testHelper.insertIntoIndex = async ( index, statements ) => {
await esClient.connection.bulk( {
index: `test_${index}`,
body: statements,
refresh: true
} );
};

testHelper.deleteFromIndex = async ( index, id ) => {
await esClient.connection.delete( {
index: `test_${index}`,
id,
refresh: true
} );
};

testHelper.loadElasticsearchFixtures = async ( ) => {
const fixtures = JSON.parse( fs.readFileSync( "schema/fixtures.js" ) );
await Promise.all( _.map( fixtures.elasticsearch, ( values, index ) => {
Expand All @@ -97,7 +105,7 @@ testHelper.loadElasticsearchFixtures = async ( ) => {
statements.push( { index: { _index: `test_${index}`, _id: v.id } } );
statements.push( v );
} );
return testHelper.insertIntoIndex( index, type, statements );
return testHelper.insertIntoIndex( index, statements );
} ) );
};

Expand All @@ -117,6 +125,37 @@ testHelper.loadPostgresqlFixtures = async ( ) => {
} ) );
};

testHelper.insertJSObjectsIntoPostgresTable = async ( table, objects ) => Promise.all(
_.map( objects, async object => {
const fields = _.keys( object );
const interpolate = _.map( new Array( fields.length ), ( n, i ) => `$${( i + 1 )}` );
const { rows } = await pgClient.query(
`INSERT INTO ${table} ("${fields.join( "\", \"" )}") VALUES (${interpolate.join( "," )}) RETURNING id`,
_.values( object )
);
return rows[0].id;
} )
);

testHelper.deleteIdsFromPostgresTable = async ( table, ids ) => {
await pgClient.query( `DELETE FROM ${table} WHERE id IN (${ids.join( "," )})` );
};

testHelper.insertJSObjectsIntoESIndex = async ( index, objects ) => {
const objectIds = _.map( objects, object => object.id );
const statements = [];
_.each( objects, obj => {
statements.push( { index: { _index: `test_${index}`, _id: obj.id } } );
statements.push( obj );
} );
await testHelper.insertIntoIndex( index, statements );
return objectIds;
};

testHelper.deleteIdsFromESIndex = async ( index, ids ) => {
await Promise.all( _.map( ids, async id => testHelper.deleteFromIndex( index, id ) ) );
};

testHelper.testInatJSPreload = async ( controller, endpoint, method, klass, done ) => {
const endpointStub = sinon.stub( endpoint, method ).callsFake( ( ) => (
new Promise( resolve => {
Expand Down Expand Up @@ -164,5 +203,9 @@ module.exports = {
loadElasticsearchFixtures: testHelper.loadElasticsearchFixtures,
loadPostgresqlFixtures: testHelper.loadPostgresqlFixtures,
testInatJSPreload: testHelper.testInatJSPreload,
testInatJSNoPreload: testHelper.testInatJSNoPreload
testInatJSNoPreload: testHelper.testInatJSNoPreload,
insertJSObjectsIntoPostgresTable: testHelper.insertJSObjectsIntoPostgresTable,
deleteIdsFromPostgresTable: testHelper.deleteIdsFromPostgresTable,
insertJSObjectsIntoESIndex: testHelper.insertJSObjectsIntoESIndex,
deleteIdsFromESIndex: testHelper.deleteIdsFromESIndex
};
34 changes: 34 additions & 0 deletions test/integration/v1/observations.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const nock = require( "nock" );
const fs = require( "fs" );
const jwt = require( "jsonwebtoken" );
const config = require( "../../../config" );
const testHelper = require( "../../../lib/test_helper" );

const fixtures = JSON.parse( fs.readFileSync( "schema/fixtures.js" ) );

Expand Down Expand Up @@ -699,6 +700,39 @@ describe( "Observations", ( ) => {
} ).expect( 200, done );
} );

it( "filters by term_value_id for multiple values", async function ( ) {
const annotationES = {
id: 2025101003,
controlled_attribute_id: 7,
controlled_value_id: 8,
concatenated_attr_val: "7|8",
vote_score_short: 0
};
const observationES = {
id: 2025101004,
user: {
id: 2025101002
},
annotations: [
annotationES
]
};
const observationESIds = await testHelper.insertJSObjectsIntoESIndex( "observations", [observationES] );
const cleanUp = async () => {
await testHelper.deleteIdsFromESIndex( "observations", observationESIds );
};

try {
await request( this.app ).get( "/v1/observations?term_id=7&term_value_id=8,9" )
.expect( res => {
expect( res.body.results.length ).to.eq( 1 );
expect( res.body.results.map( r => r.id ) ).to.contain( observationES.id );
} ).expect( 200 );
} finally {
Copy link
Author

@kfc35 kfc35 Oct 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if a test fails, it throws, so this finally block ensures the test specific data is wiped

await cleanUp();
}
} );

it( "filters by without_term_id", function ( done ) {
request( this.app ).get( "/v1/observations?without_term_id=1&id=6,7,9" )
.expect( res => {
Expand Down
50 changes: 50 additions & 0 deletions test/integration/v1/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const request = require( "supertest" );
const nock = require( "nock" );
const fs = require( "fs" );
const config = require( "../../../config" );
const testHelper = require( "../../../lib/test_helper" );

const fixtures = JSON.parse( fs.readFileSync( "schema/fixtures.js" ) );

Expand Down Expand Up @@ -247,6 +248,55 @@ describe( "Users", ( ) => {
.expect( 200, done );
} );

it( "returns monthly supporter = true even if user does not prefer to show the monthly badge", async function ( ) {
const userPG = {
id: 2025101011,
created_at: "2025-10-10 00:00:00",
updated_at: "2025-10-10 00:00:00",
last_active: "2025-10-10",
login: "20251011_monthly_supporter",
name: "Monthly Supporter",
site_id: 1,
donorbox_plan_status: "active",
donorbox_plan_type: "monthly"
};
const userES = {
id: 2025101011,
login: "20251011_monthly_supporter",
suspended: false
};
const preferencePG = {
id: 2025101013,
name: "prefers_monthly_supporter_badge",
owner_id: 2025101011,
owner_type: "User",
value: "f"
};
const userPGIds = await testHelper.insertJSObjectsIntoPostgresTable( "users", [userPG] );
const preferencePGIds = await testHelper.insertJSObjectsIntoPostgresTable( "preferences", [preferencePG] );
const userESIds = await testHelper.insertJSObjectsIntoESIndex( "users", [userES] );
const cleanUp = async () => {
await testHelper.deleteIdsFromPostgresTable( "users", userPGIds );
await testHelper.deleteIdsFromPostgresTable( "preferences", preferencePGIds );
await testHelper.deleteIdsFromESIndex( "users", userESIds );
};

const token = jwt.sign( { user_id: 2025101011 },
config.jwtSecret || "secret",
{ algorithm: "HS512" } );
try {
await request( this.app ).get( "/v1/users/me" ).set( "Authorization", token )
.expect( res => {
expect( res.body.total_results ).to.eq( 1 );
expect( res.body.results[0].monthly_supporter ).to.eq( true );
} )
.expect( "Content-Type", /json/ )
.expect( 200 );
} finally {
await cleanUp();
}
} );

_.each( [
"confirmation_sent_at",
"confirmed_at",
Expand Down