diff --git a/backend/src/middleware/filterBubble/filterBubble.js b/backend/src/middleware/filterBubble/filterBubble.js deleted file mode 100644 index bfdad5e2c..000000000 --- a/backend/src/middleware/filterBubble/filterBubble.js +++ /dev/null @@ -1,12 +0,0 @@ -import replaceParams from './replaceParams' - -const replaceFilterBubbleParams = async (resolve, root, args, context, resolveInfo) => { - args = await replaceParams(args, context) - return resolve(root, args, context, resolveInfo) -} - -export default { - Query: { - Post: replaceFilterBubbleParams, - }, -} diff --git a/backend/src/middleware/filterBubble/filterBubble.spec.js b/backend/src/middleware/filterBubble/filterBubble.spec.js index afe1df1c9..62addeece 100644 --- a/backend/src/middleware/filterBubble/filterBubble.spec.js +++ b/backend/src/middleware/filterBubble/filterBubble.spec.js @@ -5,6 +5,7 @@ import Factory from '../../seed/factories' const factory = Factory() const currentUserParams = { + id: 'u1', email: 'you@example.org', name: 'This is you', password: '1234', @@ -41,7 +42,7 @@ afterEach(async () => { await factory.cleanDatabase() }) -describe('FilterBubble middleware', () => { +describe('Filter posts by author is followed by sb.', () => { describe('given an authenticated user', () => { let authenticatedClient @@ -52,7 +53,7 @@ describe('FilterBubble middleware', () => { describe('no filter bubble', () => { it('returns all posts', async () => { - const query = '{ Post( filterBubble: {}) { title } }' + const query = '{ Post(filter: { }) { title } }' const expected = { Post: [ { title: 'This is some random post' }, @@ -65,7 +66,7 @@ describe('FilterBubble middleware', () => { describe('filtering for posts of followed users only', () => { it('returns only posts authored by followed users', async () => { - const query = '{ Post( filterBubble: { author: following }) { title } }' + const query = '{ Post( filter: { author: { followedBy_some: { id: "u1" } } }) { title } }' const expected = { Post: [{ title: 'This is the post of a followed user' }], } diff --git a/backend/src/middleware/filterBubble/replaceParams.js b/backend/src/middleware/filterBubble/replaceParams.js deleted file mode 100644 index a10b6c29d..000000000 --- a/backend/src/middleware/filterBubble/replaceParams.js +++ /dev/null @@ -1,31 +0,0 @@ -import { UserInputError } from 'apollo-server' - -export default async function replaceParams(args, context) { - const { author = 'all' } = args.filterBubble || {} - const { user } = context - - if (author === 'following') { - if (!user) - throw new UserInputError( - "You are unauthenticated - I don't know any users you are following.", - ) - - const session = context.driver.session() - let { records } = await session.run( - 'MATCH(followed:User)<-[:FOLLOWS]-(u {id: $userId}) RETURN followed.id', - { userId: context.user.id }, - ) - const followedIds = records.map(record => record.get('followed.id')) - - // carefully override `id_in` - args.filter = args.filter || {} - args.filter.author = args.filter.author || {} - args.filter.author.id_in = followedIds - - session.close() - } - - delete args.filterBubble - - return args -} diff --git a/backend/src/middleware/filterBubble/replaceParams.spec.js b/backend/src/middleware/filterBubble/replaceParams.spec.js deleted file mode 100644 index e14fda416..000000000 --- a/backend/src/middleware/filterBubble/replaceParams.spec.js +++ /dev/null @@ -1,129 +0,0 @@ -import replaceParams from './replaceParams.js' - -describe('replaceParams', () => { - let args - let context - let run - - let action = () => { - return replaceParams(args, context) - } - - beforeEach(() => { - args = {} - run = jest.fn().mockResolvedValue({ - records: [{ get: () => 1 }, { get: () => 2 }, { get: () => 3 }], - }) - context = { - driver: { - session: () => { - return { - run, - close: () => {}, - } - }, - }, - } - }) - - describe('args == ', () => { - describe('{}', () => { - it('does not crash', async () => { - await expect(action()).resolves.toEqual({}) - }) - }) - - describe('unauthenticated user', () => { - beforeEach(() => { - context.user = null - }) - - describe('{ filterBubble: { author: following } }', () => { - it('throws error', async () => { - args = { filterBubble: { author: 'following' } } - await expect(action()).rejects.toThrow('You are unauthenticated') - }) - }) - - describe('{ filterBubble: { author: all } }', () => { - it('removes filterBubble param', async () => { - const expected = {} - await expect(action()).resolves.toEqual(expected) - }) - - it('does not make database calls', async () => { - await action() - expect(run).not.toHaveBeenCalled() - }) - }) - }) - - describe('authenticated user', () => { - beforeEach(() => { - context.user = { id: 'u4711' } - }) - - describe('{ filterBubble: { author: following } }', () => { - beforeEach(() => { - args = { filterBubble: { author: 'following' } } - }) - - it('returns args object with resolved ids of followed users', async () => { - const expected = { filter: { author: { id_in: [1, 2, 3] } } } - await expect(action()).resolves.toEqual(expected) - }) - - it('makes database calls', async () => { - await action() - expect(run).toHaveBeenCalledTimes(1) - }) - - describe('given any additional filter args', () => { - describe('merges', () => { - it('empty filter object', async () => { - args.filter = {} - const expected = { filter: { author: { id_in: [1, 2, 3] } } } - await expect(action()).resolves.toEqual(expected) - }) - - it('filter.title', async () => { - args.filter = { title: 'bla' } - const expected = { filter: { title: 'bla', author: { id_in: [1, 2, 3] } } } - await expect(action()).resolves.toEqual(expected) - }) - - it('filter.author', async () => { - args.filter = { author: { name: 'bla' } } - const expected = { filter: { author: { name: 'bla', id_in: [1, 2, 3] } } } - await expect(action()).resolves.toEqual(expected) - }) - }) - }) - }) - - describe('{ filterBubble: { } }', () => { - it('removes filterBubble param', async () => { - const expected = {} - await expect(action()).resolves.toEqual(expected) - }) - - it('does not make database calls', async () => { - await action() - expect(run).not.toHaveBeenCalled() - }) - }) - - describe('{ filterBubble: { author: all } }', () => { - it('removes filterBubble param', async () => { - const expected = {} - await expect(action()).resolves.toEqual(expected) - }) - - it('does not make database calls', async () => { - await action() - expect(run).not.toHaveBeenCalled() - }) - }) - }) - }) -}) diff --git a/backend/src/middleware/index.js b/backend/src/middleware/index.js index 6bc7be000..75314abc0 100644 --- a/backend/src/middleware/index.js +++ b/backend/src/middleware/index.js @@ -13,7 +13,6 @@ import includedFields from './includedFieldsMiddleware' import orderBy from './orderByMiddleware' import validation from './validation' import notifications from './notifications' -import filterBubble from './filterBubble/filterBubble' export default schema => { const middlewares = { @@ -31,13 +30,11 @@ export default schema => { user: user, includedFields: includedFields, orderBy: orderBy, - filterBubble: filterBubble, } let order = [ 'permissions', 'activityPub', - 'filterBubble', 'password', 'dateTime', 'validation', diff --git a/backend/src/schema/types/type/Post.gql b/backend/src/schema/types/type/Post.gql index 1179c3e20..c402a1233 100644 --- a/backend/src/schema/types/type/Post.gql +++ b/backend/src/schema/types/type/Post.gql @@ -1,40 +1,3 @@ -enum FilterBubbleAuthorEnum { - following - all -} - -input FilterBubble { - author: FilterBubbleAuthorEnum -} - -type Query { - Post( - id: ID - activityId: String - objectId: String - title: String - slug: String - content: String - contentExcerpt: String - image: String - imageUpload: Upload - visibility: Visibility - deleted: Boolean - disabled: Boolean - createdAt: String - updatedAt: String - commentsCount: Int - shoutedCount: Int - shoutedByCurrentUser: Boolean - _id: String - first: Int - offset: Int - orderBy: [_PostOrdering] - filter: _PostFilter - filterBubble: FilterBubble - ): [Post] -} - type Post { id: ID! activityId: String