Skip to content

Commit

Permalink
Merge pull request #1107 from Giveth/f_1096_improve_network_filters_o…
Browse files Browse the repository at this point in the history
…n_All_project_query

Improve networks filters in all projects query
  • Loading branch information
mohammadranjbarz authored Aug 30, 2023
2 parents 8568a89 + 6ec5188 commit 12a296d
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 67 deletions.
115 changes: 92 additions & 23 deletions src/resolvers/projectResolver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -943,17 +943,19 @@ function allProjectsTestCases() {
});

it('should return projects, filter by accept donation on celo, not return when it doesnt have celo address', async () => {
const savedProject = await saveProjectDirectlyToDb({
const celoProject = await saveProjectDirectlyToDb({
...createProjectData(),
title: String(new Date().getTime()),
slug: String(new Date().getTime()),
});
const celoAddress = (await findProjectRecipientAddressByNetworkId({
projectId: savedProject.id,
networkId: NETWORK_IDS.CELO,
})) as ProjectAddress;
celoAddress.isRecipient = false;
await celoAddress.save();
});
const polygonProject = await saveProjectDirectlyToDb({
...createProjectData(),
title: String(new Date().getTime()),
slug: String(new Date().getTime()),
networkId: NETWORK_IDS.POLYGON,
});

const result = await axios.post(graphqlUrl, {
query: fetchMultiFilterAllProjectsQuery,
variables: {
Expand All @@ -972,7 +974,12 @@ function allProjectsTestCases() {
});
assert.isNotOk(
result.data.data.allProjects.projects.find(
project => Number(project.id) === Number(savedProject.id),
project => Number(project.id) === Number(polygonProject.id),
),
);
assert.isOk(
result.data.data.allProjects.projects.find(
project => Number(project.id) === Number(celoProject.id),
),
);
});
Expand Down Expand Up @@ -1013,17 +1020,13 @@ function allProjectsTestCases() {
});

it('should return projects, filter by accept donation on mainnet, not return when it doesnt have mainnet address', async () => {
const savedProject = await saveProjectDirectlyToDb({
const polygonProject = await saveProjectDirectlyToDb({
...createProjectData(),
title: String(new Date().getTime()),
slug: String(new Date().getTime()),
networkId: NETWORK_IDS.POLYGON,
});
const mainnetAddress = (await findProjectRecipientAddressByNetworkId({
projectId: savedProject.id,
networkId: NETWORK_IDS.MAIN_NET,
})) as ProjectAddress;
mainnetAddress.isRecipient = false;
await mainnetAddress.save();

const result = await axios.post(graphqlUrl, {
query: fetchMultiFilterAllProjectsQuery,
variables: {
Expand All @@ -1042,7 +1045,7 @@ function allProjectsTestCases() {
});
assert.isNotOk(
result.data.data.allProjects.projects.find(
project => Number(project.id) === Number(savedProject.id),
project => Number(project.id) === Number(polygonProject.id),
),
);
});
Expand Down Expand Up @@ -1117,31 +1120,32 @@ function allProjectsTestCases() {
);
});

it('should return projects, filter by accept donation on optimism', async () => {
it('should return projects, filter by accept donation on GOERLI', async () => {
const savedProject = await saveProjectDirectlyToDb({
...createProjectData(),
title: String(new Date().getTime()),
slug: String(new Date().getTime()),
});
const optimismAddress = (await findProjectRecipientAddressByNetworkId({
projectId: savedProject.id,
networkId: NETWORK_IDS.OPTIMISTIC,
networkId: NETWORK_IDS.GOERLI,
})) as ProjectAddress;
optimismAddress.isRecipient = true;
await optimismAddress.save();
const result = await axios.post(graphqlUrl, {
query: fetchMultiFilterAllProjectsQuery,
variables: {
filters: ['AcceptFundOnOptimism'],
filters: ['AcceptFundOnMainnet'],
sortingBy: SortingField.Newest,
limit: 50,
},
});
result.data.data.allProjects.projects.forEach(project => {
assert.isOk(
project.addresses.find(
address =>
address.isRecipient === true &&
address.networkId === NETWORK_IDS.OPTIMISTIC,
address.networkId === NETWORK_IDS.GOERLI,
),
);
});
Expand All @@ -1151,7 +1155,41 @@ function allProjectsTestCases() {
),
);
});
it('should return projects, filter by accept donation on optimism, not return when it doesnt have optimism address', async () => {

it('should return projects, filter by accept donation on ALFAJORES', async () => {
const alfajoresProject = await saveProjectDirectlyToDb({
...createProjectData(),
title: String(new Date().getTime()),
slug: String(new Date().getTime()),
networkId: NETWORK_IDS.CELO_ALFAJORES,
});

const result = await axios.post(graphqlUrl, {
query: fetchMultiFilterAllProjectsQuery,
variables: {
filters: ['AcceptFundOnCelo'],
sortingBy: SortingField.Newest,
},
});
result.data.data.allProjects.projects.forEach(project => {
assert.isOk(
project.addresses.find(
address =>
(address.isRecipient === true &&
// We return both Celo and Alfajores when sending AcceptFundOnCelo filter
address.networkId === NETWORK_IDS.CELO_ALFAJORES) ||
address.networkId === NETWORK_IDS.CELO,
),
);
});
assert.isOk(
result.data.data.allProjects.projects.find(
project => Number(project.id) === Number(alfajoresProject.id),
),
);
});

it('should return projects, filter by accept donation on optimism', async () => {
const savedProject = await saveProjectDirectlyToDb({
...createProjectData(),
title: String(new Date().getTime()),
Expand All @@ -1161,7 +1199,7 @@ function allProjectsTestCases() {
projectId: savedProject.id,
networkId: NETWORK_IDS.OPTIMISTIC,
})) as ProjectAddress;
optimismAddress.isRecipient = false;
optimismAddress.isRecipient = true;
await optimismAddress.save();
const result = await axios.post(graphqlUrl, {
query: fetchMultiFilterAllProjectsQuery,
Expand All @@ -1179,12 +1217,43 @@ function allProjectsTestCases() {
),
);
});
assert.isNotOk(
assert.isOk(
result.data.data.allProjects.projects.find(
project => Number(project.id) === Number(savedProject.id),
),
);
});
it('should return projects, filter by accept donation on optimism, not return when it doesnt have optimism address', async () => {
const gnosisProject = await saveProjectDirectlyToDb({
...createProjectData(),
title: String(new Date().getTime()),
slug: String(new Date().getTime()),
networkId: NETWORK_IDS.XDAI,
});

const result = await axios.post(graphqlUrl, {
query: fetchMultiFilterAllProjectsQuery,
variables: {
filters: ['AcceptFundOnOptimism'],
sortingBy: SortingField.Newest,
},
});
result.data.data.allProjects.projects.forEach(project => {
assert.isOk(
project.addresses.find(
address =>
(address.isRecipient === true &&
address.networkId === NETWORK_IDS.OPTIMISTIC) ||
address.networkId === NETWORK_IDS.OPTIMISM_GOERLI,
),
);
});
assert.isNotOk(
result.data.data.allProjects.projects.find(
project => Number(project.id) === Number(gnosisProject.id),
),
);
});
it('should return projects, filter by accept donation on gnosis, return all addresses', async () => {
await redis.flushall(); // clear cache from other tests
const savedProject = await saveProjectDirectlyToDb({
Expand Down
111 changes: 69 additions & 42 deletions src/resolvers/projectResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,7 @@ export class ProjectResolver {
if (
(filter === FilterField.AcceptFundOnGnosis ||
filter === FilterField.AcceptFundOnCelo ||
filter === FilterField.AcceptFundOnMainnet ||
filter === FilterField.AcceptFundOnPolygon ||
filter === FilterField.AcceptFundOnOptimism) &&
filterValue
Expand Down Expand Up @@ -535,53 +536,79 @@ export class ProjectResolver {

static addFiltersQuery(
query: SelectQueryBuilder<Project>,
filtersArray: FilterField[] = [],
allFiltersArray: FilterField[] = [],
) {
if (!filtersArray || filtersArray.length === 0) return query;
query = query.andWhere(
new Brackets(subQuery => {
filtersArray.forEach(filter => {
if (filter === FilterField.AcceptGiv) {
// only giving Blocks do not accept Giv
return subQuery.andWhere(`project.${filter} IS NULL`);
}

if (filter === FilterField.GivingBlock) {
return subQuery.andWhere('project.givingBlocksId IS NOT NULL');
}

if (filter === FilterField.BoostedWithGivPower) {
return subQuery.andWhere(`projectPower.totalPower > 0`);
}
if (filter === FilterField.ActiveQfRound) {
return subQuery.andWhere(
`EXISTS (
if (!allFiltersArray || allFiltersArray.length === 0) return query;
const networkFiltersArray: FilterField[] = [];
const otherFiltersArray: FilterField[] = [];
allFiltersArray.forEach(filter => {
if (
filter === FilterField.AcceptFundOnGnosis ||
filter === FilterField.AcceptFundOnCelo ||
filter === FilterField.AcceptFundOnPolygon ||
filter === FilterField.AcceptFundOnMainnet ||
filter === FilterField.AcceptFundOnOptimism
) {
networkFiltersArray.push(filter);
} else {
otherFiltersArray.push(filter);
}
});

// Other filters
if (otherFiltersArray.length > 0) {
query = query.andWhere(
new Brackets(subQuery => {
otherFiltersArray.forEach(filter => {
if (filter === FilterField.AcceptGiv) {
// only giving Blocks do not accept Giv
return subQuery.andWhere(`project.${filter} IS NULL`);
}

if (filter === FilterField.GivingBlock) {
return subQuery.andWhere('project.givingBlocksId IS NOT NULL');
}

if (filter === FilterField.BoostedWithGivPower) {
return subQuery.andWhere(`projectPower.totalPower > 0`);
}
if (filter === FilterField.ActiveQfRound) {
return subQuery.andWhere(
`EXISTS (
SELECT 1
FROM project_qf_rounds_qf_round
INNER JOIN qf_round on qf_round.id = project_qf_rounds_qf_round."qfRoundId"
WHERE project_qf_rounds_qf_round."projectId" = project.id AND qf_round."isActive" = true
)`,
);
}

if (
(filter === FilterField.AcceptFundOnGnosis ||
filter === FilterField.AcceptFundOnCelo ||
filter === FilterField.AcceptFundOnPolygon ||
filter === FilterField.AcceptFundOnMainnet ||
filter === FilterField.AcceptFundOnOptimism) &&
filter
) {
const networkIds: number[] = [];
);
}
return subQuery.andWhere(`project.${filter} = true`);
});
}),
);
}

// Network filters
if (networkFiltersArray.length > 0) {
query = query.andWhere(
new Brackets(subQuery => {
const networkIds: number[] = [];
networkFiltersArray.forEach(filter => {
if (filter === FilterField.AcceptFundOnGnosis) {
networkIds.push(NETWORK_IDS.XDAI);
}
if (filter === FilterField.AcceptFundOnMainnet) {
networkIds.push(NETWORK_IDS.MAIN_NET);

// Add this to make sure works on Staging
networkIds.push(NETWORK_IDS.GOERLI);
}

if (filter === FilterField.AcceptFundOnCelo) {
networkIds.push(NETWORK_IDS.CELO);

// Add this to make sure works on Staging
networkIds.push(NETWORK_IDS.CELO_ALFAJORES);
}

if (filter === FilterField.AcceptFundOnPolygon) {
Expand All @@ -590,24 +617,24 @@ export class ProjectResolver {

if (filter === FilterField.AcceptFundOnOptimism) {
networkIds.push(NETWORK_IDS.OPTIMISTIC);

// Add this to make sure works on Staging
networkIds.push(NETWORK_IDS.OPTIMISM_GOERLI);
}
});

return subQuery.andWhere(
`EXISTS (
return subQuery.andWhere(
`EXISTS (
SELECT *
FROM project_address
WHERE "isRecipient" = true AND "networkId" IN (${networkIds.join(
', ',
)}) AND "projectId" = project.id
)`,
);
}

return subQuery.andWhere(`project.${filter} = true`);
});
}),
);

);
}),
);
}
return query;
}

Expand Down
16 changes: 14 additions & 2 deletions test/testUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ export interface CreateProjectData {
projectUpdateCreationDate?: Date;
verificationStatus?: string;
image?: string;
networkId?: number;
}

export const saveUserDirectlyToDb = async (
Expand Down Expand Up @@ -226,15 +227,26 @@ export const saveProjectDirectlyToDb = async (
adminUser: user,
}).save();

for (const networkId of Object.values(NETWORK_IDS)) {
if (projectData.networkId) {
await addNewProjectAddress({
project,
user,
isRecipient: true,
address: projectData.walletAddress,
networkId,
networkId: projectData.networkId,
});
} else {
for (const networkId of Object.values(NETWORK_IDS)) {
await addNewProjectAddress({
project,
user,
isRecipient: true,
address: projectData.walletAddress,
networkId,
});
}
}

// default projectUpdate for liking projects
// this was breaking updateAt tests as it was running update hooks sometime in the future.
// Found no other way to avoid triggering the hooks.
Expand Down

0 comments on commit 12a296d

Please sign in to comment.