import { favoriteStatusAs, postAs, postReplyAs, reblogStatusAs } from '../serverActions' import { loginAsFoobar } from '../roles' import { getAriaSetSize, getFavoritesCount, getNthStatus, getNthStatusContent, getReblogsCount, getUrl, goBack, scrollToStatus, sleep, validateTimeline } from '../utils' fixture`132-threads-and-updates.js` .page`http://localhost:4002` test('thread for a status that is not cached locally', async t => { const { id: statusId } = await postAs('baz', 'yo here is a post you have never seen before') await postReplyAs('baz', 'yep you have never seen this', statusId) await loginAsFoobar(t) await t .navigateTo(`/statuses/${statusId}`) .expect(getNthStatusContent(1).innerText).contains('you have never seen before') .expect(getNthStatusContent(2).innerText).contains('yep you have never') }) test('thread for a reply that is not cached locally', async t => { const { id: statusId } = await postAs('baz', 'number one') const { id: replyId } = await postReplyAs('baz', 'number two', statusId) await loginAsFoobar(t) await t .navigateTo(`/statuses/${replyId}`) .expect(getNthStatusContent(1).innerText).contains('number one') .expect(getNthStatusContent(2).innerText).contains('number two') }) test('thread for a status that is cached but the rest is not', async t => { const { id: id1 } = await postAs('foobar', 'post number one') const { id: id2 } = await postReplyAs('baz', 'post number two', id1) await postReplyAs('baz', 'post number three', id2) await loginAsFoobar(t) await t .expect(getNthStatusContent(1).innerText).contains('post number one') .click(getNthStatus(1)) .expect(getUrl()).contains('/statuses') .expect(getNthStatusContent(1).innerText).contains('post number one') .expect(getNthStatusContent(2).innerText).contains('post number two') .expect(getNthStatusContent(3).innerText).contains('post number three') }) test('thread for a reply that is cached but the rest is not', async t => { const { id: id1 } = await postAs('baz', 'post number one') const { id: id2 } = await postReplyAs('baz', 'post number two', id1) await postReplyAs('foobar', 'post number three', id2) await loginAsFoobar(t) await t .expect(getNthStatusContent(1).innerText).contains('post number three') .click(getNthStatus(1)) .expect(getUrl()).contains('/statuses') .expect(getNthStatusContent(1).innerText).contains('post number one') .expect(getNthStatusContent(2).innerText).contains('post number two') .expect(getNthStatusContent(3).innerText).contains('post number three') }) test('updates the status fav/reblog count when you click on status', async t => { const { id } = await postAs('foobar', 'my happy happy post') await loginAsFoobar(t) async function assertReblogAndFavCount (reblogs, favs) { await t .expect(getReblogsCount()).eql(reblogs) .expect(getFavoritesCount()).eql(favs) } await t.click(getNthStatus(1)) await assertReblogAndFavCount(0, 0) await goBack() await favoriteStatusAs('baz', id) await sleep(1000) await t.click(getNthStatus(1)) await assertReblogAndFavCount(0, 1) await goBack() await reblogStatusAs('baz', id) await sleep(1000) await t.click(getNthStatus(1)) await assertReblogAndFavCount(1, 1) }) test('updates the thread when you click on status', async t => { const { id } = await postAs('foobar', 'my super happy post') await loginAsFoobar(t) await t .click(getNthStatus(1)) .expect(getAriaSetSize()).eql('1') await goBack() const { id: id2 } = await postReplyAs('baz', 'that is very happy', id) await t .click(getNthStatus(1)) .expect(getAriaSetSize()).eql('2') .expect(getNthStatusContent(2).innerText).contains('that is very happy') await goBack() await postReplyAs('baz', 'that is super duper happy', id2) await t .click(getNthStatus(1)) .expect(getAriaSetSize()).eql('3') .expect(getNthStatusContent(3).innerText).contains('super duper happy') await goBack() }) test('updates the thread of a reply when you click on it', async t => { const { id: id1 } = await postAs('baz', 'uno') const { id: id2 } = await postReplyAs('foobar', 'dos', id1) await loginAsFoobar(t) await t .expect(getNthStatusContent(1).innerText).contains('dos') .click(getNthStatus(1)) .expect(getAriaSetSize()).eql('2') .expect(getNthStatusContent(1).innerText).contains('uno') .expect(getNthStatusContent(2).innerText).contains('dos') await goBack() const { id: id3 } = await postReplyAs('baz', 'tres', id2) await t .click(getNthStatus(1)) .expect(getAriaSetSize()).eql('3') .expect(getNthStatusContent(3).innerText).contains('tres') await goBack() await postReplyAs('baz', 'quatro', id3) await t .click(getNthStatus(1)) .expect(getAriaSetSize()).eql('4') .expect(getNthStatusContent(4).innerText).contains('quatro') await goBack() }) test('complex thread is in correct order', async t => { const { id: a } = await postAs('foobar', 'a') const { id: b } = await postReplyAs('baz', 'b', a) const { id: c } = await postReplyAs('baz', 'c', b) const { id: a1 } = await postReplyAs('baz', 'a1', a) const { id: d } = await postReplyAs('baz', 'd', c) const { id: a2 } = await postReplyAs('baz', 'a2', a1) const { id: b1 } = await postReplyAs('baz', 'b1', b) const { id: a3 } = await postReplyAs('baz', 'a3', a2) await postReplyAs('baz', 'e', d) await postReplyAs('baz', 'b2', b1) await postReplyAs('baz', 'a4', a3) await postReplyAs('baz', 'a1a', a1) await loginAsFoobar(t) await t.click(getNthStatus(1)) const order = 'a b c d e b1 b2 a1 a2 a3 a4 a1a'.split(' ') await validateTimeline(t, order.map(content => ({ content }))) }) test('complex thread is in correct order - original poster involved', async t => { const { id: a } = await postAs('foobar', 'a-original') const { id: b } = await postReplyAs('baz', 'b', a) const { id: c } = await postReplyAs('baz', 'c', b) const { id: a1 } = await postReplyAs('foobar', 'a1', a) const { id: d } = await postReplyAs('baz', 'd', c) const { id: a2 } = await postReplyAs('foobar', 'a2', a1) const { id: b1 } = await postReplyAs('baz', 'b1', b) const { id: a3 } = await postReplyAs('foobar', 'a3', a2) await postReplyAs('baz', 'e', d) await postReplyAs('baz', 'b2', b1) await postReplyAs('foobar', 'a4', a3) await postReplyAs('baz', 'a1a', a1) await loginAsFoobar(t) await scrollToStatus(t, 5) await t .expect(getNthStatusContent(5).innerText).contains('a-original') .click(getNthStatus(5)) const order = 'a-original a1 a2 a3 a4 b c d e b1 b2 a1a'.split(' ') await validateTimeline(t, order.map(content => ({ content }))) }) test('complex thread is in correct order - with ancestors', async t => { const { id: ancestor1 } = await postAs('foobar', 'ancestor1') const { id: ancestor2 } = await postReplyAs('foobar', 'ancestor2', ancestor1) const { id: a } = await postReplyAs('foobar', 'a-root', ancestor2) const { id: b } = await postReplyAs('baz', 'b', a) const { id: c } = await postReplyAs('baz', 'c', b) const { id: a1 } = await postReplyAs('baz', 'a1', a) const { id: d } = await postReplyAs('baz', 'd', c) const { id: a2 } = await postReplyAs('baz', 'a2', a1) const { id: b1 } = await postReplyAs('baz', 'b1', b) const { id: a3 } = await postReplyAs('baz', 'a3', a2) await postReplyAs('baz', 'e', d) await postReplyAs('baz', 'b2', b1) await postReplyAs('baz', 'a4', a3) await postReplyAs('baz', 'a1a', a1) await loginAsFoobar(t) await scrollToStatus(t, 5) await t .expect(getNthStatusContent(1).innerText).contains('a-root') .click(getNthStatus(1)) const order = 'ancestor1 ancestor2 a-root b c d e b1 b2 a1 a2 a3 a4 a1a'.split(' ') await validateTimeline(t, order.map(content => ({ content }))) }) test('complex thread is in correct order - with mixed self-replies', async t => { const { id: a } = await postAs('foobar', 'a') await sleep(1000) const { id: b } = await postReplyAs('baz', 'b', a) await sleep(1000) const { id: c } = await postReplyAs('baz', 'c', b) await sleep(1000) const { id: a1 } = await postReplyAs('baz', 'a1', a) await sleep(1000) const { id: d } = await postReplyAs('baz', 'd', c) await sleep(1000) const { id: a2 } = await postReplyAs('baz', 'a2', a1) await sleep(1000) const { id: b1 } = await postReplyAs('baz', 'b1', b) await sleep(1000) const { id: a3 } = await postReplyAs('baz', 'a3', a2) await sleep(1000) await postReplyAs('baz', 'e', d) await sleep(1000) await postReplyAs('baz', 'b2', b1) await sleep(1000) await postReplyAs('baz', 'a4', a3) await sleep(1000) await postReplyAs('baz', 'a1a', a1) await sleep(1000) // reply chain: foobar -> foobar -> baz -> foobar -> foobar // when foobar replies to itself after replying to baz, is it promoted? // see https://github.com/tootsuite/mastodon/pull/9320#issuecomment-440705662 const { id: mixed1 } = await postReplyAs('foobar', 'foobar-mixed1', a) await sleep(1000) const { id: mixed2 } = await postReplyAs('baz', 'baz-mixed2', mixed1) await sleep(1000) const { id: mixed3 } = await postReplyAs('foobar', 'foobar-mixed3', mixed2) await sleep(1000) await postReplyAs('foobar', 'foobar-mixed4', mixed3) await sleep(2000) await loginAsFoobar(t) await t.click(getNthStatus(4)) const order = 'a foobar-mixed1 b c d e b1 b2 a1 a2 a3 a4 a1a baz-mixed2 foobar-mixed3 foobar-mixed4'.split(' ') await validateTimeline(t, order.map(content => ({ content }))) }) test('complex thread is in correct order - with mixed self-replies 2', async t => { const { id: a } = await postAs('foobar', 'a') await sleep(1000) const { id: b } = await postReplyAs('baz', 'b', a) await sleep(1000) const { id: c } = await postReplyAs('baz', 'c', b) await sleep(1000) const { id: a1 } = await postReplyAs('baz', 'a1', a) await sleep(1000) const { id: d } = await postReplyAs('baz', 'd', c) await sleep(1000) const { id: a2 } = await postReplyAs('baz', 'a2', a1) await sleep(1000) const { id: b1 } = await postReplyAs('baz', 'b1', b) await sleep(1000) const { id: a3 } = await postReplyAs('baz', 'a3', a2) await sleep(1000) await postReplyAs('baz', 'e', d) await sleep(1000) await postReplyAs('baz', 'b2', b1) await sleep(1000) await postReplyAs('baz', 'a4', a3) await sleep(1000) await postReplyAs('baz', 'a1a', a1) await sleep(1000) // reply chain: foobar -> foobar -> baz -> foobar -> foobar // when foobar replies to itself after replying to baz, is it promoted? // see https://github.com/tootsuite/mastodon/pull/9320#issuecomment-440705662 const { id: mixed1 } = await postReplyAs('foobar', 'foobar-mixed1', a) await sleep(1000) const { id: mixed2 } = await postReplyAs('baz', 'baz-mixed2', mixed1) await sleep(1000) const { id: mixed3 } = await postReplyAs('foobar', 'foobar-mixed3', mixed2) await sleep(1000) await postReplyAs('foobar', 'foobar-mixed4', mixed3) await sleep(1000) await postReplyAs('foobar', 'foobar-mixed1a', a) await sleep(1000) await postReplyAs('foobar', 'foobar-mixed1b', a) await sleep(1000) await postReplyAs('foobar', 'foobar-mixed2a', mixed1) await sleep(2000) await loginAsFoobar(t) await scrollToStatus(t, 7) await t.click(getNthStatus(7)) const order = ('a foobar-mixed1 foobar-mixed2a foobar-mixed1a foobar-mixed1b ' + 'b c d e b1 b2 a1 a2 a3 a4 a1a baz-mixed2 foobar-mixed3 foobar-mixed4').split(' ') await validateTimeline(t, order.map(content => ({ content }))) })