mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-12 23:35:58 +00:00
test(cypress): Cover "Pinned post" feature
* Implement cypress tests
- Start implementation of cypress tests for pinned posts
* Test that Admin can pin a post
- Tests the process of an admin pinning a post
* Resolve failing tests
- Fix ordering of posts immediately after pinning posts by reloading page
- Check that tests are pinned posts are displayed first for role user
* Refactor to seperate the initialization
- Of the post data created in the database during setup
* Fix toaster test
* test(cypress): Add missing parts for pin feature
* docs(cucumber): Link to admin 🥒 folder
* Follow @mattwr18's suggestions
* test(backend): Order pinned posts like frontend
@mattwr18 I think this was a false negative.
Co-authored-by: Robert Schäfer <git@roschaefer.de>
This commit is contained in:
parent
42c08d4296
commit
d49afc25cf
@ -41,4 +41,6 @@ export default {
|
||||
language: { type: 'string', allow: [null] },
|
||||
imageBlurred: { type: 'boolean', default: false },
|
||||
imageAspectRatio: { type: 'float', default: 1.0 },
|
||||
pinned: { type: 'boolean', default: null, valid: [null, true] },
|
||||
pinnedAt: { type: 'string', isoDate: true },
|
||||
}
|
||||
|
||||
@ -682,58 +682,62 @@ describe('UpdatePost', () => {
|
||||
})
|
||||
|
||||
describe('PostOrdering', () => {
|
||||
let pinnedPost, admin
|
||||
beforeEach(async () => {
|
||||
;[pinnedPost] = await Promise.all([
|
||||
neode.create('Post', {
|
||||
id: 'im-a-pinned-post',
|
||||
pinned: true,
|
||||
}),
|
||||
neode.create('Post', {
|
||||
id: 'i-was-created-after-pinned-post',
|
||||
createdAt: '2019-10-22T17:26:29.070Z', // this should always be 3rd
|
||||
}),
|
||||
])
|
||||
admin = await user.update({
|
||||
role: 'admin',
|
||||
name: 'Admin',
|
||||
updatedAt: new Date().toISOString(),
|
||||
await factory.create('Post', {
|
||||
id: 'im-a-pinned-post',
|
||||
createdAt: '2019-11-22T17:26:29.070Z',
|
||||
pinned: true,
|
||||
})
|
||||
await factory.create('Post', {
|
||||
id: 'i-was-created-before-pinned-post',
|
||||
// fairly old, so this should be 3rd
|
||||
createdAt: '2019-10-22T17:26:29.070Z',
|
||||
})
|
||||
await admin.relateTo(pinnedPost, 'pinned')
|
||||
})
|
||||
|
||||
it('pinned post appear first even when created before other posts', async () => {
|
||||
const postOrderingQuery = gql`
|
||||
query($orderBy: [_PostOrdering]) {
|
||||
Post(orderBy: $orderBy) {
|
||||
id
|
||||
pinnedAt
|
||||
describe('order by `pinned_asc` and `createdAt_desc`', () => {
|
||||
beforeEach(() => {
|
||||
// this is the ordering in the frontend
|
||||
variables = { orderBy: ['pinned_asc', 'createdAt_desc'] }
|
||||
})
|
||||
|
||||
it('pinned post appear first even when created before other posts', async () => {
|
||||
const postOrderingQuery = gql`
|
||||
query($orderBy: [_PostOrdering]) {
|
||||
Post(orderBy: $orderBy) {
|
||||
id
|
||||
pinned
|
||||
createdAt
|
||||
pinnedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
const expected = {
|
||||
data: {
|
||||
Post: [
|
||||
{
|
||||
id: 'im-a-pinned-post',
|
||||
pinnedAt: expect.any(String),
|
||||
},
|
||||
{
|
||||
id: 'p9876',
|
||||
pinnedAt: null,
|
||||
},
|
||||
{
|
||||
id: 'i-was-created-after-pinned-post',
|
||||
pinnedAt: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
errors: undefined,
|
||||
}
|
||||
variables = { orderBy: ['pinned_desc', 'createdAt_desc'] }
|
||||
await expect(query({ query: postOrderingQuery, variables })).resolves.toMatchObject(
|
||||
expected,
|
||||
)
|
||||
`
|
||||
await expect(query({ query: postOrderingQuery, variables })).resolves.toMatchObject({
|
||||
data: {
|
||||
Post: [
|
||||
{
|
||||
id: 'im-a-pinned-post',
|
||||
pinned: true,
|
||||
createdAt: '2019-11-22T17:26:29.070Z',
|
||||
pinnedAt: expect.any(String),
|
||||
},
|
||||
{
|
||||
id: 'p9876',
|
||||
pinned: null,
|
||||
createdAt: expect.any(String),
|
||||
pinnedAt: null,
|
||||
},
|
||||
{
|
||||
id: 'i-was-created-before-pinned-post',
|
||||
pinned: null,
|
||||
createdAt: '2019-10-22T17:26:29.070Z',
|
||||
pinnedAt: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -21,11 +21,15 @@ export default function create() {
|
||||
categoryIds: [],
|
||||
imageBlurred: false,
|
||||
imageAspectRatio: 1.333,
|
||||
pinned: null,
|
||||
}
|
||||
args = {
|
||||
...defaults,
|
||||
...args,
|
||||
}
|
||||
// Convert false to null
|
||||
args.pinned = args.pinned || null
|
||||
|
||||
args.slug = args.slug || slugify(args.title, { lower: true })
|
||||
args.contentExcerpt = args.contentExcerpt || args.content
|
||||
|
||||
@ -50,9 +54,21 @@ export default function create() {
|
||||
if (author && authorId) throw new Error('You provided both author and authorId')
|
||||
if (authorId) author = await neodeInstance.find('User', authorId)
|
||||
author = author || (await factoryInstance.create('User'))
|
||||
|
||||
const post = await neodeInstance.create('Post', args)
|
||||
await post.relateTo(author, 'author')
|
||||
|
||||
if (args.pinned) {
|
||||
args.pinnedAt = args.pinnedAt || new Date().toISOString()
|
||||
if (!args.pinnedBy) {
|
||||
const admin = await factoryInstance.create('User', {
|
||||
role: 'admin',
|
||||
updatedAt: new Date().toISOString(),
|
||||
})
|
||||
await admin.relateTo(post, 'pinned')
|
||||
args.pinnedBy = admin
|
||||
}
|
||||
}
|
||||
|
||||
await Promise.all(categories.map(c => c.relateTo(post, 'post')))
|
||||
await Promise.all(tags.map(t => t.relateTo(post, 'post')))
|
||||
return post
|
||||
|
||||
@ -249,10 +249,12 @@ Shows automatically related actions for existing post.
|
||||
|
||||
### Administration
|
||||
|
||||
[Cucumber Features](https://github.com/Human-Connection/Human-Connection/tree/master/cypress/integration/administration)
|
||||
|
||||
* Provide Admin-Interface to send Users Invite Code
|
||||
* Static Pages for Data Privacy Statement ...
|
||||
* Create, edit and delete Announcements
|
||||
* Show Announcements on top of User Interface
|
||||
* Pin a post to inform users
|
||||
|
||||
### Invitation
|
||||
|
||||
|
||||
36
cypress/integration/administration/PinPost.feature
Normal file
36
cypress/integration/administration/PinPost.feature
Normal file
@ -0,0 +1,36 @@
|
||||
Feature: Pin a post
|
||||
As an admin
|
||||
I want to pin a post so that it always appears at the top
|
||||
In order to make sure all network users read it - e.g. notify people about security incidents, maintenance downtimes
|
||||
|
||||
|
||||
Background:
|
||||
Given we have the following posts in our database:
|
||||
| id | title | pinned | createdAt |
|
||||
| p1 | Some other post | | 2020-01-21 |
|
||||
| p2 | Houston we have a problem | x | 2020-01-20 |
|
||||
| p3 | Yet another post | | 2020-01-19 |
|
||||
|
||||
Scenario: Pinned post always appears on the top of the newsfeed
|
||||
Given I am logged in with a "user" role
|
||||
Then the first post on the landing page has the title:
|
||||
"""
|
||||
Houston we have a problem
|
||||
"""
|
||||
And the post with title "Houston we have a problem" has a ribbon for pinned posts
|
||||
|
||||
Scenario: Ordinary users cannot pin a post
|
||||
Given I am logged in with a "user" role
|
||||
When I open the content menu of post "Yet another post"
|
||||
Then there is no button to pin a post
|
||||
|
||||
Scenario: Admins are allowed to pin a post
|
||||
Given I am logged in with a "admin" role
|
||||
And I open the content menu of post "Yet another post"
|
||||
When I click on 'Pin post'
|
||||
Then I see a toaster with "Post pinned successfully"
|
||||
And the first post on the landing page has the title:
|
||||
"""
|
||||
Yet another post
|
||||
"""
|
||||
And the post with title "Yet another post" has a ribbon for pinned posts
|
||||
@ -44,3 +44,31 @@ Then("I should see an abreviated version of my comment", () => {
|
||||
Then("the editor should be cleared", () => {
|
||||
cy.get(".ProseMirror p").should("have.class", "is-empty");
|
||||
});
|
||||
|
||||
When("I open the content menu of post {string}", (title)=> {
|
||||
cy.contains('.post-card', title)
|
||||
.find('.content-menu .base-button')
|
||||
.click()
|
||||
})
|
||||
|
||||
When("I click on 'Pin post'", (string)=> {
|
||||
cy.get("a.ds-menu-item-link").contains("Pin post")
|
||||
.click()
|
||||
})
|
||||
|
||||
Then("there is no button to pin a post", () => {
|
||||
cy.get("a.ds-menu-item-link")
|
||||
.should('contain', "Report Post") // sanity check
|
||||
.should('not.contain', "Pin post")
|
||||
})
|
||||
|
||||
And("the post with title {string} has a ribbon for pinned posts", (title) => {
|
||||
cy.get("article.post-card").contains(title)
|
||||
.parent()
|
||||
.find("div.ribbon.ribbon--pinned")
|
||||
.should("contain", "Announcement")
|
||||
})
|
||||
|
||||
Then("I see a toaster with {string}", (title) => {
|
||||
cy.get(".iziToast-message").should("contain", title);
|
||||
})
|
||||
|
||||
@ -170,5 +170,4 @@ When("they have a post someone has reported", () => {
|
||||
authorId: 'annnoying-user',
|
||||
title,
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
@ -212,6 +212,7 @@ Given("we have the following posts in our database:", table => {
|
||||
...postAttributes,
|
||||
deleted: Boolean(postAttributes.deleted),
|
||||
disabled: Boolean(postAttributes.disabled),
|
||||
pinned: Boolean(postAttributes.pinned),
|
||||
categoryIds: ['cat-456']
|
||||
}
|
||||
cy.factory().create("Post", postAttributes);
|
||||
|
||||
@ -9,10 +9,10 @@ Feature: Report and Moderate
|
||||
|
||||
Background:
|
||||
Given we have the following user accounts:
|
||||
| id | name |
|
||||
| u67 | David Irving |
|
||||
| id | name |
|
||||
| u67 | David Irving |
|
||||
| annoying-user | I'm gonna mute Moderators and Admins HA HA HA |
|
||||
|
||||
|
||||
Given we have the following posts in our database:
|
||||
| authorId | id | title | content |
|
||||
| u67 | p1 | The Truth about the Holocaust | It never existed! |
|
||||
|
||||
@ -132,7 +132,7 @@ export default {
|
||||
)
|
||||
},
|
||||
isPinned() {
|
||||
return this.post && this.post.pinnedBy
|
||||
return this.post && this.post.pinned
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
||||
@ -52,6 +52,7 @@ export const postFragment = gql`
|
||||
}
|
||||
pinnedAt
|
||||
imageAspectRatio
|
||||
pinned
|
||||
}
|
||||
`
|
||||
|
||||
|
||||
@ -413,8 +413,8 @@
|
||||
"name": "Take action"
|
||||
},
|
||||
"menu": {
|
||||
"edit": "Edit Post",
|
||||
"delete": "Delete Post",
|
||||
"edit": "Edit post",
|
||||
"delete": "Delete post",
|
||||
"pin": "Pin post",
|
||||
"pinnedSuccessfully": "Post pinned successfully!",
|
||||
"unpin": "Unpin post",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user