From 55b11ed7c897c87e6e272a44e8438683b4212af6 Mon Sep 17 00:00:00 2001
From: AkiraFukushima
Date: Sun, 20 Jan 2019 22:44:03 +0900
Subject: [PATCH 1/2] refs #209 Add unit tests for TimelineSpace
---
spec/unit/store/TimelineSpace.spec.js | 67 +++++++++++++++++++
src/renderer/store/App.js | 2 +-
src/renderer/store/TimelineSpace.js | 2 +-
.../store/TimelineSpace/Modals/Jump.js | 2 +-
4 files changed, 70 insertions(+), 3 deletions(-)
create mode 100644 spec/unit/store/TimelineSpace.spec.js
diff --git a/spec/unit/store/TimelineSpace.spec.js b/spec/unit/store/TimelineSpace.spec.js
new file mode 100644
index 00000000..25e975cf
--- /dev/null
+++ b/spec/unit/store/TimelineSpace.spec.js
@@ -0,0 +1,67 @@
+import TimelineSpace from '~/src/renderer/store/TimelineSpace'
+import unreadSettings from '~/src/constants/unreadNotification'
+
+describe('TimelineSpace', () => {
+ describe('mutations', () => {
+ let state
+ beforeEach(() => {
+ state = {
+ account: {
+ domain: '',
+ _id: '',
+ username: ''
+ },
+ loading: false,
+ emojis: [],
+ tootMax: 500,
+ unreadNotification: {
+ direct: unreadSettings.Direct.default,
+ local: unreadSettings.Local.default,
+ public: unreadSettings.Public.default
+ },
+ useWebsocket: false,
+ pleroma: false
+ }
+ })
+
+ describe('updateEmojis', () => {
+ it('should be updated', () => {
+ TimelineSpace.mutations.updateEmojis(state, [
+ {
+ shortcode: 'emacs',
+ url: 'http://example.com/emacs'
+ },
+ {
+ shortcode: 'ruby',
+ url: 'http://example.com/ruby'
+ }
+ ])
+ expect(state.emojis).toEqual([
+ {
+ name: ':emacs:',
+ image: 'http://example.com/emacs'
+ },
+ {
+ name: ':ruby:',
+ image: 'http://example.com/ruby'
+ }
+ ])
+ })
+ })
+
+ describe('updateTootMax', () => {
+ describe('value is null', () => {
+ it('should be updated with 500', () => {
+ TimelineSpace.mutations.updateTootMax(state, null)
+ expect(state.tootMax).toEqual(500)
+ })
+ })
+ describe('value is not null', () => {
+ it('should be updated', () => {
+ TimelineSpace.mutations.updateTootMax(state, 1200)
+ expect(state.tootMax).toEqual(1200)
+ })
+ })
+ })
+ })
+})
diff --git a/src/renderer/store/App.js b/src/renderer/store/App.js
index e7c1f416..96e0fe73 100644
--- a/src/renderer/store/App.js
+++ b/src/renderer/store/App.js
@@ -1,5 +1,5 @@
import { ipcRenderer } from 'electron'
-import router from '../router'
+import router from '@/router'
import { LightTheme, DarkTheme, SolarizedLightTheme, SolarizedDarkTheme, KimbieDarkTheme } from '../utils/theme'
import DisplayStyle from '~/src/constants/displayStyle'
import Theme from '~/src/constants/theme'
diff --git a/src/renderer/store/TimelineSpace.js b/src/renderer/store/TimelineSpace.js
index 0ab673ee..6abf622d 100644
--- a/src/renderer/store/TimelineSpace.js
+++ b/src/renderer/store/TimelineSpace.js
@@ -5,7 +5,7 @@ import SideMenu from './TimelineSpace/SideMenu'
import HeaderMenu from './TimelineSpace/HeaderMenu'
import Modals from './TimelineSpace/Modals'
import Contents from './TimelineSpace/Contents'
-import router from '../router'
+import router from '@/router'
import unreadSettings from '~/src/constants/unreadNotification'
const TimelineSpace = {
diff --git a/src/renderer/store/TimelineSpace/Modals/Jump.js b/src/renderer/store/TimelineSpace/Modals/Jump.js
index 214acc54..4ff75ea6 100644
--- a/src/renderer/store/TimelineSpace/Modals/Jump.js
+++ b/src/renderer/store/TimelineSpace/Modals/Jump.js
@@ -1,4 +1,4 @@
-import router from '../../../router'
+import router from '@/router'
import i18n from '~/src/config/i18n'
const Jump = {
From 487307142c35844eee3947b7872c3ea4a729ff7b Mon Sep 17 00:00:00 2001
From: AkiraFukushima
Date: Tue, 22 Jan 2019 23:47:16 +0900
Subject: [PATCH 2/2] refs #209 Add integration tests for TimelineSpace
---
spec/integration/store/TimelineSpace.spec.js | 242 +++++++++++++++++++
1 file changed, 242 insertions(+)
create mode 100644 spec/integration/store/TimelineSpace.spec.js
diff --git a/spec/integration/store/TimelineSpace.spec.js b/spec/integration/store/TimelineSpace.spec.js
new file mode 100644
index 00000000..1180614d
--- /dev/null
+++ b/spec/integration/store/TimelineSpace.spec.js
@@ -0,0 +1,242 @@
+import Mastodon from 'megalodon'
+import { createLocalVue } from '@vue/test-utils'
+import Vuex from 'vuex'
+import { ipcMain } from '~/spec/mock/electron'
+import TimelineSpace from '~/src/renderer/store/TimelineSpace'
+import unreadSettings from '~/src/constants/unreadNotification'
+
+jest.genMockFromModule('megalodon')
+jest.mock('megalodon')
+
+const state = () => {
+ return {
+ account: {
+ domain: '',
+ _id: '',
+ username: ''
+ },
+ loading: false,
+ emojis: [],
+ tootMax: 500,
+ unreadNotification: {
+ direct: true,
+ local: true,
+ public: true
+ },
+ useWebsocket: false,
+ pleroma: false
+ }
+}
+
+const homeStore = {
+ namespaced: true,
+ actions: {
+ fetchTimeline: jest.fn()
+ }
+}
+
+const notificationStore = {
+ namespaced: true,
+ actions: {
+ fetchNotifications: jest.fn()
+ }
+}
+
+const DMStore = {
+ namespaced: true,
+ actions: {
+ fetchTimeline: jest.fn()
+ }
+}
+
+const LocalStore = {
+ namespaced: true,
+ actions: {
+ fetchLocalTimeline: jest.fn()
+ }
+}
+
+const PublicStore = {
+ namespaced: true,
+ actions: {
+ fetchPublicTimeline: jest.fn()
+ }
+}
+
+const contentsStore = {
+ namespaced: true,
+ modules: {
+ Home: homeStore,
+ Notifications: notificationStore,
+ DirectMessages: DMStore,
+ Local: LocalStore,
+ Public: PublicStore
+ }
+}
+
+const initStore = () => {
+ return {
+ namespaced: true,
+ modules: {
+ Contents: contentsStore
+ },
+ state: state(),
+ actions: TimelineSpace.actions,
+ mutations: TimelineSpace.mutations
+ }
+}
+
+describe('TimelineSpace', () => {
+ let store
+ let localVue
+
+ beforeEach(() => {
+ localVue = createLocalVue()
+ localVue.use(Vuex)
+ store = new Vuex.Store({
+ modules: {
+ TimelineSpace: initStore()
+ }
+ })
+ })
+
+ describe('localAccount', () => {
+ describe('account already exists', () => {
+ beforeEach(() => {
+ ipcMain.once('get-local-account', (event, _id) => {
+ event.sender.send('response-get-local-account', {
+ username: 'test'
+ })
+ })
+ })
+ it('should be updated', async () => {
+ await store.dispatch('TimelineSpace/localAccount', 1)
+ expect(store.state.TimelineSpace.account.username).toEqual('test')
+ })
+ })
+
+ describe('account does not exist', () => {
+ beforeEach(() => {
+ ipcMain.once('get-local-account', (event, _id) => {
+ event.sender.send('response-get-local-account', {})
+ })
+ ipcMain.once('update-account', (event, _account) => {
+ event.sender.send('response-update-account', {
+ username: 'fetched'
+ })
+ })
+ })
+ it('should be fetched', async () => {
+ await store.dispatch('TimelineSpace/localAccount', 1)
+ expect(store.state.TimelineSpace.account.username).toEqual('fetched')
+ })
+ })
+ })
+
+ describe('detectPleroma', () => {
+ describe('API is pleroma', () => {
+ it('should be detected', async () => {
+ const mockResponse = {
+ version: 'Pleroma v0.9.9'
+ }
+ Mastodon.get.mockResolvedValue(mockResponse)
+ await store.dispatch('TimelineSpace/detectPleroma')
+ expect(store.state.TimelineSpace.pleroma).toEqual(true)
+ expect(store.state.TimelineSpace.useWebsocket).toEqual(true)
+ })
+ })
+ describe('API is not pleroma', () => {
+ it('should be detected', async () => {
+ const mockResponse = {
+ version: '2.7.0'
+ }
+ Mastodon.get.mockResolvedValue(mockResponse)
+ await store.dispatch('TimelineSpace/detectPleroma')
+ expect(store.state.TimelineSpace.pleroma).toEqual(false)
+ expect(store.state.TimelineSpace.useWebsocket).toEqual(false)
+ })
+ })
+ })
+
+ describe('fetchEmojis', () => {
+ it('should be updated', async () => {
+ const mockResponse = [
+ {
+ shortcode: 'emacs',
+ url: 'http://example.com/emacs'
+ },
+ {
+ shortcode: 'ruby',
+ url: 'http://example.com/ruby'
+ }
+ ]
+ Mastodon.get.mockResolvedValue(mockResponse)
+ await store.dispatch('TimelineSpace/fetchEmojis', {})
+ expect(store.state.TimelineSpace.emojis).toEqual([
+ {
+ name: ':emacs:',
+ image: 'http://example.com/emacs'
+ },
+ {
+ name: ':ruby:',
+ image: 'http://example.com/ruby'
+ }
+ ])
+ })
+ })
+
+ describe('fetchInstance', () => {
+ it('should be updated', async () => {
+ const mockResponse = {
+ max_toot_chars: 5000
+ }
+ Mastodon.get.mockResolvedValue(mockResponse)
+ await store.dispatch('TimelineSpace/fetchInstance', {})
+ expect(store.state.TimelineSpace.tootMax).toEqual(5000)
+ })
+ })
+
+ describe('loadUnreadNotification', () => {
+ describe('success', () => {
+ it('should be updated', async () => {
+ ipcMain.once('get-unread-notification', (event, _) => {
+ event.sender.send('response-get-unread-notification', {
+ direct: false,
+ local: false,
+ public: false
+ })
+ })
+ await store.dispatch('TimelineSpace/loadUnreadNotification')
+ expect(store.state.TimelineSpace.unreadNotification).toEqual({
+ direct: false,
+ local: false,
+ public: false
+ })
+ })
+ })
+ describe('error', () => {
+ it('should be set default', async () => {
+ ipcMain.once('get-unread-notification', (event, _) => {
+ event.sender.send('error-get-unread-notification', new Error())
+ })
+ await store.dispatch('TimelineSpace/loadUnreadNotification')
+ expect(store.state.TimelineSpace.unreadNotification).toEqual({
+ direct: unreadSettings.Direct.default,
+ local: unreadSettings.Local.default,
+ public: unreadSettings.Public.default
+ })
+ })
+ })
+ })
+
+ describe('fetchContentsTimelines', () => {
+ it('should be called', async () => {
+ await store.dispatch('TimelineSpace/fetchContentsTimelines', {})
+ expect(homeStore.actions.fetchTimeline).toHaveBeenCalled()
+ expect(notificationStore.actions.fetchNotifications).toHaveBeenCalled()
+ expect(DMStore.actions.fetchTimeline).toHaveBeenCalled()
+ expect(LocalStore.actions.fetchLocalTimeline).toHaveBeenCalled()
+ expect(PublicStore.actions.fetchPublicTimeline).toHaveBeenCalled()
+ })
+ })
+})