tests added for click count

This commit is contained in:
Moriz Wahl 2021-02-22 20:49:33 +01:00
parent 7c5e5d971e
commit 4862d53196
6 changed files with 111 additions and 12 deletions

View File

@ -130,6 +130,7 @@ Factory.define('post')
deleted: false, deleted: false,
imageBlurred: false, imageBlurred: false,
imageAspectRatio: 1.333, imageAspectRatio: 1.333,
clickedCount: 0,
}) })
.attr('pinned', ['pinned'], (pinned) => { .attr('pinned', ['pinned'], (pinned) => {
// Convert false to null // Convert false to null

View File

@ -1,33 +1,33 @@
const createRelatedCypher = (relation) => ` const createRelatedCypher = (relation) => `
MATCH (user:User { id: $currentUser}) MATCH (user:User { id: $currentUser})
MATCH (post:Post { id: $postId})<-[r:${relation}]-(u:User) MATCH (post:Post { id: $postId})
OPTIONAL MATCH (post)<-[r:${relation}]-(u:User)
WHERE NOT u.disabled AND NOT u.deleted WHERE NOT u.disabled AND NOT u.deleted
WITH user, post, count(DISTINCT u) AS count WITH user, post, count(DISTINCT u) AS count
MERGE (user)-[relation:${relation} { }]->(post) MERGE (user)-[relation:${relation} { }]->(post)
ON CREATE ON CREATE
SET relation.count = 1, SET relation.count = 1,
relation.createdAt = toString(datetime()), relation.createdAt = toString(datetime()),
post.clickCount = count + 1 post.clickedCount = count + 1
ON MATCH ON MATCH
SET relation.count = relation.count + 1, SET relation.count = relation.count + 1,
relation.updatedAt = toString(datetime()), relation.updatedAt = toString(datetime()),
post.clickCount = count post.clickedCount = count
RETURN user, post, relation RETURN user, post, relation
` `
const setPostCounter = async (postId, relation, context) => { const setPostCounter = async (postId, relation, context) => {
const { user: currentUser } = context const {
user: { id: currentUser },
} = context
const session = context.driver.session() const session = context.driver.session()
try { try {
await session.writeTransaction((txc) => { await session.writeTransaction((txc) => {
return txc.run( return txc.run(createRelatedCypher(relation), { currentUser, postId })
createRelatedCypher(relation),
{ currentUser, postId },
)
}) })
} finally { } finally {
session.close() session.close()
} }
} }
const userClickedPost = async (resolve, root, args, context, info) => { const userClickedPost = async (resolve, root, args, context, info) => {

View File

@ -0,0 +1,98 @@
import Factory, { cleanDatabase } from '../db/factories'
import { gql } from '../helpers/jest'
import { getNeode, getDriver } from '../db/neo4j'
import createServer from '../server'
import { createTestClient } from 'apollo-server-testing'
let query, aUser, bUser, post, authenticatedUser, variables
const driver = getDriver()
const neode = getNeode()
const postQuery = gql`
query($id: ID) {
Post(id: $id) {
clickedCount
}
}
`
beforeAll(async () => {
await cleanDatabase()
aUser = await Factory.build('user', {
id: 'a-user',
})
bUser = await Factory.build('user', {
id: 'b-user',
})
post = await Factory.build('post')
authenticatedUser = await aUser.toJson()
const { server } = createServer({
context: () => {
return {
driver,
neode,
user: authenticatedUser,
}
},
})
query = createTestClient(server).query
})
afterAll(async () => {
await cleanDatabase()
})
describe('middleware/userInteractions', () => {
describe('given one post', () => {
it('does not change clickedCount when queried without ID', async () => {
await expect(query({ query: postQuery, variables })).resolves.toMatchObject({
data: {
Post: expect.arrayContaining([
{
clickedCount: 0,
},
]),
},
})
})
it('changes clickedCount when queried with ID', async () => {
variables = { id: post.get('id') }
await expect(query({ query: postQuery, variables })).resolves.toMatchObject({
data: {
Post: expect.arrayContaining([
{
clickedCount: 1,
},
]),
},
})
})
it('does not change clickedCount when same user queries the post again', async () => {
await expect(query({ query: postQuery, variables })).resolves.toMatchObject({
data: {
Post: expect.arrayContaining([
{
clickedCount: 1,
},
]),
},
})
})
it('changes clickedCount when another user queries the post', async () => {
authenticatedUser = await bUser.toJson()
await expect(query({ query: postQuery, variables })).resolves.toMatchObject({
data: {
Post: expect.arrayContaining([
{
clickedCount: 2,
},
]),
},
})
})
})
})

View File

@ -22,6 +22,7 @@ export default {
contentExcerpt: { type: 'string', allow: [null] }, contentExcerpt: { type: 'string', allow: [null] },
deleted: { type: 'boolean', default: false }, deleted: { type: 'boolean', default: false },
disabled: { type: 'boolean', default: false }, disabled: { type: 'boolean', default: false },
clickedCount: { type: 'int', default: 0 },
notified: { notified: {
type: 'relationship', type: 'relationship',
relationship: 'NOTIFIED', relationship: 'NOTIFIED',

View File

@ -88,6 +88,7 @@ export default {
SET post += $params SET post += $params
SET post.createdAt = toString(datetime()) SET post.createdAt = toString(datetime())
SET post.updatedAt = toString(datetime()) SET post.updatedAt = toString(datetime())
SET post.clickedCount = 0
WITH post WITH post
MATCH (author:User {id: $userId}) MATCH (author:User {id: $userId})
MERGE (post)<-[:WROTE]-(author) MERGE (post)<-[:WROTE]-(author)

View File

@ -157,9 +157,7 @@ type Post {
) )
clickedCount: Int! clickedCount: Int!
@cypher(
statement: "MATCH (this)<-[:CLICKED]-(r:User) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)"
)
emotions: [EMOTED] emotions: [EMOTED]
emotionsCount: Int! emotionsCount: Int!
@cypher(statement: "MATCH (this)<-[emoted:EMOTED]-(:User) RETURN COUNT(DISTINCT emoted)") @cypher(statement: "MATCH (this)<-[emoted:EMOTED]-(:User) RETURN COUNT(DISTINCT emoted)")