This repository was archived by the owner on Nov 20, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
create GET /ideas?filter[title][like] #62
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1006,4 +1006,143 @@ describe('read lists of ideas', () => { | |
| }); | ||
| }); | ||
| }); | ||
|
|
||
| describe('GET /ideas?filter[title][like]=string1,string2,string3', () => { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So do I understand correctly that the client will be responsible for splitting the user's raw input into separate words (and send them as separate query items)?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking about it as about keywords, where each keyword is added separately and consciously by the user on the client side. Not like dividing a string into smaller pieces. |
||
| let user0; | ||
| // create and save testing data | ||
| beforeEach(async () => { | ||
| const data = { | ||
| users: 2, | ||
| verifiedUsers: [0], | ||
| ideas: [ [{title:'idea-title1'}, 0], [{title:'idea-title2-keyword1'}, 0], [{title:'idea-title3-keyword2'}, 0], [{title:'idea-title4-keyword3'}, 0], [{title:'idea-title5-keyword2-keyword3'}, 0], [{title:'idea-title6-keyword1'}, 0], [{title:'idea-title7-keyword1-keyword4'}, 0] ] | ||
| }; | ||
|
|
||
| dbData = await dbHandle.fill(data); | ||
|
|
||
| [user0, ] = dbData.users; | ||
| }); | ||
|
|
||
| context('logged in', () => { | ||
|
|
||
| beforeEach(() => { | ||
| agent = agentFactory.logged(user0); | ||
| }); | ||
|
|
||
| context('valid data', () => { | ||
|
|
||
| it('[find ideas with one word] 200 and return array of matched ideas', async () => { | ||
|
|
||
| // request | ||
| const response = await agent | ||
| .get('/ideas?filter[title][like]=keyword1') | ||
| .expect(200); | ||
|
|
||
| // we should find 2 ideas... | ||
| should(response.body).have.property('data').Array().length(3); | ||
|
|
||
| // sorted by creation date desc | ||
| should(response.body.data.map(idea => idea.attributes.title)) | ||
| .eql(['idea-title2-keyword1','idea-title6-keyword1', 'idea-title7-keyword1-keyword4']); | ||
|
|
||
| }); | ||
|
|
||
|
|
||
| it('[find ideas with two words] 200 and return array of matched ideas', async () => { | ||
|
|
||
| // request | ||
| const response = await agent | ||
| .get('/ideas?filter[title][like]=keyword2,keyword3') | ||
| .expect(200); | ||
|
|
||
| // we should find 4 ideas... | ||
| should(response.body).have.property('data').Array().length(3); | ||
|
|
||
| // sorted by creation date desc | ||
| should(response.body.data.map(idea => idea.attributes.title)) | ||
| .eql(['idea-title5-keyword2-keyword3', 'idea-title3-keyword2', 'idea-title4-keyword3']); | ||
| }); | ||
|
|
||
| it('[find ideas with word not present in any] 200 and return array of matched ideas', async () => { | ||
|
|
||
| // request | ||
| const response = await agent | ||
| .get('/ideas?filter[title][like]=keyword10') | ||
| .expect(200); | ||
|
|
||
| // we should find 0 ideas... | ||
| should(response.body).have.property('data').Array().length(0); | ||
|
|
||
| }); | ||
|
|
||
| it('[pagination] offset and limit the results', async () => { | ||
| const response = await agent | ||
| .get('/ideas?filter[title][like]=keyword1&page[offset]=1&page[limit]=2') | ||
| .expect(200); | ||
|
|
||
| // we should find 3 ideas | ||
| should(response.body).have.property('data').Array().length(2); | ||
|
|
||
| // sorted by creation date desc | ||
| should(response.body.data.map(idea => idea.attributes.title)) | ||
| .eql(['idea-title6-keyword1', 'idea-title7-keyword1-keyword4']); | ||
| }); | ||
|
|
||
| it('should be fine to provide a keyword which includes empty spaces and/or special characters', async () => { | ||
| // request | ||
| await agent | ||
| .get('/ideas?filter[title][like]=keyword , aa,1-i') | ||
| .expect(200); | ||
| }); | ||
|
|
||
| }); | ||
|
|
||
| context('invalid data', () => { | ||
|
|
||
| it('[too many keywords] 400', async () => { | ||
| await agent | ||
| .get('/ideas?filter[title][like]=keyword1,keyword2,keyword3,keyword4,keyword5,keyword6,keyword7,keyword8,keyword9,keyword10,keyword11') | ||
| .expect(400); | ||
| }); | ||
|
|
||
| it('[empty keywords] 400', async () => { | ||
| await agent | ||
| .get('/ideas?filter[title][like]=keyword1,') | ||
| .expect(400); | ||
| }); | ||
|
|
||
| it('[too long keywords] 400', async () => { | ||
| await agent | ||
| .get(`/ideas?filter[title][like]=keyword1,${'a'.repeat(257)}`) | ||
| .expect(400); | ||
| }); | ||
|
|
||
| it('[keywords spaces only] 400', async () => { | ||
| await agent | ||
| .get('/ideas?filter[title][like]= ,keyword2') | ||
| .expect(400); | ||
| }); | ||
|
|
||
| it('[invalid pagination] 400', async () => { | ||
| await agent | ||
| .get('/ideas?filter[title][like]=keyword1&page[offset]=1&page[limit]=21') | ||
| .expect(400); | ||
| }); | ||
|
|
||
| it('[unexpected query params] 400', async () => { | ||
| await agent | ||
| .get('/ideas?filter[title][like]=keyword1&additional[param]=3&page[offset]=1&page[limit]=3') | ||
| .expect(400); | ||
| }); | ||
| }); | ||
| }); | ||
|
|
||
| context('not logged in', () => { | ||
| it('403', async () => { | ||
| await agent | ||
| .get('/ideas?filter[title][like]=keyword1') | ||
| .expect(403); | ||
| }); | ||
| }); | ||
| }); | ||
|
|
||
| }); | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could also think whether we need substring search or just word or perfix search (those can be faster)
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More efficient search can be nice, actually. Especially if we get a lot of ideas and if the search has lower computational complexity (O(n) vs. O(1)?). It can be done later, when it's needed, can't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Arango supports word-based prefix matching from what I got on slack(this has probably some index support). If we want something different we can explore it later.
FOR idea IN FULLTEXT(ideas, "title", CONCAT("prefix:", CONCAT_SEPARATOR(",|prefix:", @Keywords)))
RETURN idea
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
opened issue #65 for this