mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
Merge branch 'master' of github.com:Human-Connection/Human-Connection into neo4j_data_migrations
This commit is contained in:
commit
f8f62cc71f
@ -67,20 +67,20 @@
|
||||
"linkifyjs": "~2.1.8",
|
||||
"lodash": "~4.17.14",
|
||||
"merge-graphql-schemas": "^1.7.6",
|
||||
"metascraper": "^5.10.5",
|
||||
"metascraper-audio": "^5.10.5",
|
||||
"metascraper": "^5.10.6",
|
||||
"metascraper-audio": "^5.10.6",
|
||||
"metascraper-author": "^5.10.6",
|
||||
"metascraper-clearbit-logo": "^5.3.0",
|
||||
"metascraper-date": "^5.10.6",
|
||||
"metascraper-description": "^5.10.6",
|
||||
"metascraper-image": "^5.10.5",
|
||||
"metascraper-lang": "^5.10.5",
|
||||
"metascraper-lang": "^5.10.6",
|
||||
"metascraper-lang-detector": "^4.10.2",
|
||||
"metascraper-logo": "^5.10.5",
|
||||
"metascraper-publisher": "^5.10.5",
|
||||
"metascraper-soundcloud": "^5.10.6",
|
||||
"metascraper-title": "^5.10.6",
|
||||
"metascraper-url": "^5.10.5",
|
||||
"metascraper-url": "^5.10.6",
|
||||
"metascraper-video": "^5.10.5",
|
||||
"metascraper-youtube": "^5.10.6",
|
||||
"migrate": "^1.6.2",
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -6154,12 +6154,12 @@ merge2@^1.3.0:
|
||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81"
|
||||
integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==
|
||||
|
||||
metascraper-audio@^5.10.5:
|
||||
version "5.10.5"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-audio/-/metascraper-audio-5.10.5.tgz#7f292bfb66516753672a52dec083fabdc05edfbd"
|
||||
integrity sha512-S3Wrzfgf0zpl8rjYN1NBMEz0FCcpbtTV/+QxktLqSeJv/kzLfUWrYQadOMv9++EQpIc8umBgVwHeZ6+1TCBVgA==
|
||||
metascraper-audio@^5.10.6:
|
||||
version "5.10.6"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-audio/-/metascraper-audio-5.10.6.tgz#095892445b90d40bc54e54f69536a80e36fd9e4c"
|
||||
integrity sha512-wTVtYK8Ico82caIi6HlkyGgUaBC21X/vhT2aQ4LKcg+gHoOhJcmWNd5me9VhaRJ7gTV/7yKkL5A54fBcjcn8Kg==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^5.10.5"
|
||||
"@metascraper/helpers" "^5.10.6"
|
||||
|
||||
metascraper-author@^5.10.6:
|
||||
version "5.10.6"
|
||||
@ -6206,12 +6206,12 @@ metascraper-lang-detector@^4.10.2:
|
||||
franc "~4.0.0"
|
||||
iso-639-3 "~1.1.0"
|
||||
|
||||
metascraper-lang@^5.10.5:
|
||||
version "5.10.5"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-lang/-/metascraper-lang-5.10.5.tgz#8d62f8a398863b8bf785f730319f0cf0a5bff3ba"
|
||||
integrity sha512-DzpZSkze6p/MDIrK4g+jl/lbgTIBW8FdERCD8LnmzFLtSYDr/U3e9SB+d7wLlrWSPm0JBKkVajwzkQGx6GKqGQ==
|
||||
metascraper-lang@^5.10.6:
|
||||
version "5.10.6"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-lang/-/metascraper-lang-5.10.6.tgz#d4130257f6604095e9af8d796a6bde5815f6c667"
|
||||
integrity sha512-JDhNbP1iSnPV7d6PklIIdBSzlwqbtvH+n810Isa5/PGuvUkJzNkTAUN+eTM1i6YcTlMp1N2gYsQG9uwfpMwFog==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^5.10.5"
|
||||
"@metascraper/helpers" "^5.10.6"
|
||||
|
||||
metascraper-logo@^5.10.5:
|
||||
version "5.10.5"
|
||||
@ -6243,12 +6243,12 @@ metascraper-title@^5.10.6:
|
||||
"@metascraper/helpers" "^5.10.6"
|
||||
lodash "~4.17.15"
|
||||
|
||||
metascraper-url@^5.10.5:
|
||||
version "5.10.5"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-url/-/metascraper-url-5.10.5.tgz#b4a9951143e19f39e3bf62d93e060ece9bdba6d4"
|
||||
integrity sha512-fdPPDk1/hq8vRTxwnLtUV55FpclJfhfBLxYLekTSRGqQbqSlXLNpncj2LjrvRUc0yw0oT2fEsTYzb56OQmh2Aw==
|
||||
metascraper-url@^5.10.6:
|
||||
version "5.10.6"
|
||||
resolved "https://registry.yarnpkg.com/metascraper-url/-/metascraper-url-5.10.6.tgz#45f0ea173fecfe56d60b3cddd3c018f9f4fd9b92"
|
||||
integrity sha512-7F6uAsI27iVXxUMwwzXH0ret81CX1jgtoGCMz+TvZkyS0z4aUs0r8QpYRYEQuXrW+JawRVik0up54F/ScslObQ==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^5.10.5"
|
||||
"@metascraper/helpers" "^5.10.6"
|
||||
|
||||
metascraper-video@^5.10.5:
|
||||
version "5.10.5"
|
||||
@ -6268,12 +6268,12 @@ metascraper-youtube@^5.10.6:
|
||||
is-reachable "~4.0.0"
|
||||
p-locate "~4.1.0"
|
||||
|
||||
metascraper@^5.10.5:
|
||||
version "5.10.5"
|
||||
resolved "https://registry.yarnpkg.com/metascraper/-/metascraper-5.10.5.tgz#d23a6f76ea0ae3222aa88ed4e93026926bdacbdd"
|
||||
integrity sha512-2ZeEbI9668ByIurvyZC8fmE6PGMgJ3kWWQYtmGUVsfK2USuoq4z1e9SpP9s4+fSRpZNyaAZFrnRUtpu9E9chiQ==
|
||||
metascraper@^5.10.6:
|
||||
version "5.10.6"
|
||||
resolved "https://registry.yarnpkg.com/metascraper/-/metascraper-5.10.6.tgz#d1249577a768566b86bd099cc2256df45cf05181"
|
||||
integrity sha512-mPEDvoyHLWb0AlTE05W43vfKGgBJ99s5AYAhB4IiRgGR9uq8j7/ktTZaS/+pyFopYrEoe71L/k4KbYgNPQRASA==
|
||||
dependencies:
|
||||
"@metascraper/helpers" "^5.10.5"
|
||||
"@metascraper/helpers" "^5.10.6"
|
||||
cheerio "~1.0.0-rc.3"
|
||||
cheerio-advanced-selectors "~2.0.1"
|
||||
lodash "~4.17.15"
|
||||
|
||||
@ -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