summaryrefslogtreecommitdiffstats
path: root/tests/javascript/unit/components/FeedItem.spec.ts
blob: 88991201fbb1ddd43edaddc1822bf639e5296b49 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import { shallowMount, createLocalVue, Wrapper } from '@vue/test-utils'

import FeedItem from '../../../../src/components/FeedItem.vue'
import { ACTIONS } from '../../../../src/store'

describe('FeedItem.vue', () => {
	'use strict'
	const localVue = createLocalVue()
	let wrapper: Wrapper<FeedItem>

	const mockItem = {
		feedId: 1,
		title: 'feed item',
		pubDate: Date.now() / 1000,
	}
	const mockFeed = {
		id: 1,
	}

	const dispatchStub = jest.fn()
	beforeAll(() => {
		wrapper = shallowMount(FeedItem, {
			propsData: {
				item: mockItem,
			},
			localVue,
			mocks: {
				$store: {
					getters: {
						feeds: [mockFeed],
					},
					state: {
						feeds: [],
						folders: [],
					},
					dispatch: dispatchStub,
				},
			},
		})
	})

	beforeEach(() => {
		dispatchStub.mockReset()
	})

	it('should initialize without expanded and without keepUnread', () => {
		expect(wrapper.vm.$data.expanded).toBeFalsy()
		expect(wrapper.vm.$data.keepUnread).toBeFalsy()
	})

	it('should expand when clicked', async () => {
		await wrapper.find('.feed-item-row').trigger('click')

		expect(wrapper.vm.$data.expanded).toBe(true)
	})

	it('should format date correctly', () => {
		const epoch = Date.now() // Provide an epoch timestamp
		const formattedDate = (wrapper.vm as any).formatDate(epoch)

		expect(formattedDate).toEqual(new Date(epoch).toLocaleString())
	})

	it('should format datetime correctly', () => {
		const epoch = Date.now() // Provide an epoch timestamp
		const formattedDate = (wrapper.vm as any).formatDatetime(epoch)

		expect(formattedDate).toEqual(new Date(epoch).toISOString())
	})

	it('should calculate relative timestamp correctly', () => {
		const currentTimestamp = Date.now()
		let pastTimestamp = currentTimestamp - 1000 * 10 // 10 seconds ago

		let relativeTimestamp = (wrapper.vm as any).getRelativeTimestamp(pastTimestamp)

		expect(relativeTimestamp).toEqual('10 seconds')

		pastTimestamp = currentTimestamp - 1000 * 60 * 10 // 10 minutes ago

		relativeTimestamp = (wrapper.vm as any).getRelativeTimestamp(pastTimestamp)

		expect(relativeTimestamp).toEqual('10 minutes ago')
	})

	it('should retrieve feed by ID', () => {
		const feed = (wrapper.vm as any).getFeed(mockFeed.id)

		expect(feed).toEqual(mockFeed)
	})

	describe('markRead', () => {
		it('should mark item as read when keepUnread is false', () => {
			wrapper.vm.$data.keepUnread = false;
			(wrapper.vm as any).markRead(wrapper.vm.$props.item)

			expect(dispatchStub).toHaveBeenCalledWith(ACTIONS.MARK_READ, {
				item: wrapper.vm.$props.item,
			})
		})

		it('should not mark item as read when keepUnread is true', () => {
			wrapper.vm.$data.keepUnread = true;
			(wrapper.vm as any).markRead(wrapper.vm.$data.item)

			expect(dispatchStub).not.toHaveBeenCalled()
		})
	})

	it('toggles keepUnread state', () => {
		const initialKeepUnread = wrapper.vm.$data.keepUnread;
		(wrapper.vm as any).toggleKeepUnread(wrapper.vm.$data.item)
		const updatedKeepUnread = wrapper.vm.$data.keepUnread

		expect(updatedKeepUnread).toBe(!initialKeepUnread)
	})

	it('toggles starred state', () => {
		wrapper.vm.$props.item.starred = true;

		(wrapper.vm as any).toggleStarred(wrapper.vm.$props.item)
		expect(dispatchStub).toHaveBeenCalledWith(ACTIONS.UNSTAR_ITEM, {
			item: wrapper.vm.$props.item,
		})

		wrapper.vm.$props.item.starred = false;

		(wrapper.vm as any).toggleStarred(wrapper.vm.$props.item)
		expect(dispatchStub).toHaveBeenCalledWith(ACTIONS.STAR_ITEM, {
			item: wrapper.vm.$props.item,
		})
	})

	xit('TODO test: getMediaType(mime: any): audio | video | false', () => {
		// TODO: finish tests after audio/video playback is supported
	})

	xit('TODO test: play(item: any): void', () => {
		// TODO: finish tests after audio/video playback is supported
	})
})