Files
atom/packages/about/spec/update-view-spec.js
2018-08-21 15:27:37 -07:00

281 lines
13 KiB
JavaScript

const {shell} = require('electron')
const {it, fit, ffit, fffit, beforeEach, afterEach} = require('./helpers/async-spec-helpers') // eslint-disable-line no-unused-vars
const main = require('../lib/main')
const AboutView = require('../lib/components/about-view')
const UpdateView = require('../lib/components/update-view')
const MockUpdater = require('./mocks/updater')
describe('UpdateView', () => {
let aboutElement
let updateManager
let workspaceElement
let scheduler
beforeEach(async () => {
let storage = {}
spyOn(window.localStorage, 'setItem').andCallFake((key, value) => {
storage[key] = value
})
spyOn(window.localStorage, 'getItem').andCallFake((key) => {
return storage[key]
})
workspaceElement = atom.views.getView(atom.workspace)
await atom.packages.activatePackage('about')
spyOn(atom.autoUpdater, 'getState').andReturn('idle')
spyOn(atom.autoUpdater, 'checkForUpdate')
spyOn(atom.autoUpdater, 'platformSupportsUpdates').andReturn(true)
})
describe('when the About page is open', () => {
beforeEach(async () => {
jasmine.attachToDOM(workspaceElement)
await atom.workspace.open('atom://about')
aboutElement = workspaceElement.querySelector('.about')
updateManager = main.model.state.updateManager
scheduler = AboutView.getScheduler()
})
describe('when the updates are not supported by the platform', () => {
beforeEach(async () => {
atom.autoUpdater.platformSupportsUpdates.andReturn(false)
updateManager.resetState()
await scheduler.getNextUpdatePromise()
})
it('hides the auto update UI and shows the update instructions link', async () => {
expect(aboutElement.querySelector('.about-update-action-button')).not.toBeVisible()
expect(aboutElement.querySelector('.about-auto-updates')).not.toBeVisible()
})
it('opens the update instructions page when the instructions link is clicked', async () => {
spyOn(shell, 'openExternal')
let link = aboutElement.querySelector('.app-unsupported .about-updates-instructions')
link.click()
let args = shell.openExternal.mostRecentCall.args
expect(shell.openExternal).toHaveBeenCalled()
expect(args[0]).toContain('installing-atom')
})
})
describe('when updates are supported by the platform', () => {
beforeEach(async () => {
atom.autoUpdater.platformSupportsUpdates.andReturn(true)
updateManager.resetState()
await scheduler.getNextUpdatePromise()
})
it('shows the auto update UI', () => {
expect(aboutElement.querySelector('.about-updates')).toBeVisible()
})
it('shows the correct panels when the app checks for updates and there is no update available', async () => {
expect(aboutElement.querySelector('.about-default-update-message')).toBeVisible()
MockUpdater.checkForUpdate()
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.app-up-to-date')).not.toBeVisible()
expect(aboutElement.querySelector('.app-checking-for-updates')).toBeVisible()
MockUpdater.updateNotAvailable()
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.app-up-to-date')).toBeVisible()
expect(aboutElement.querySelector('.app-checking-for-updates')).not.toBeVisible()
})
it('shows the correct panels when the app checks for updates and encounters an error', async () => {
expect(aboutElement.querySelector('.about-default-update-message')).toBeVisible()
MockUpdater.checkForUpdate()
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.app-up-to-date')).not.toBeVisible()
expect(aboutElement.querySelector('.app-checking-for-updates')).toBeVisible()
spyOn(atom.autoUpdater, 'getErrorMessage').andReturn('an error message')
MockUpdater.updateError()
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.app-update-error')).toBeVisible()
expect(aboutElement.querySelector('.app-error-message').textContent).toBe('an error message')
expect(aboutElement.querySelector('.app-checking-for-updates')).not.toBeVisible()
expect(aboutElement.querySelector('.about-update-action-button').disabled).toBe(false)
expect(aboutElement.querySelector('.about-update-action-button').textContent).toBe('Check now')
})
it('shows the correct panels and button states when the app checks for updates and an update is downloaded', async () => {
expect(aboutElement.querySelector('.about-default-update-message')).toBeVisible()
expect(aboutElement.querySelector('.about-update-action-button').disabled).toBe(false)
expect(aboutElement.querySelector('.about-update-action-button').textContent).toBe('Check now')
MockUpdater.checkForUpdate()
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.app-up-to-date')).not.toBeVisible()
expect(aboutElement.querySelector('.app-checking-for-updates')).toBeVisible()
expect(aboutElement.querySelector('.about-update-action-button').disabled).toBe(true)
expect(aboutElement.querySelector('.about-update-action-button').textContent).toBe('Check now')
MockUpdater.downloadUpdate()
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.app-checking-for-updates')).not.toBeVisible()
expect(aboutElement.querySelector('.app-downloading-update')).toBeVisible()
// TODO: at some point it would be nice to be able to cancel an update download, and then this would be a cancel button
expect(aboutElement.querySelector('.about-update-action-button').disabled).toBe(true)
expect(aboutElement.querySelector('.about-update-action-button').textContent).toBe('Check now')
MockUpdater.finishDownloadingUpdate('42.0.0')
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.app-downloading-update')).not.toBeVisible()
expect(aboutElement.querySelector('.app-update-available-to-install')).toBeVisible()
expect(aboutElement.querySelector('.app-update-available-to-install .about-updates-version').textContent).toBe('42.0.0')
expect(aboutElement.querySelector('.about-update-action-button').disabled).toBe(false)
expect(aboutElement.querySelector('.about-update-action-button').textContent).toBe('Restart and install')
})
it('opens the release notes for the downloaded release when the release notes link are clicked', async () => {
MockUpdater.finishDownloadingUpdate('1.2.3')
await scheduler.getNextUpdatePromise()
spyOn(shell, 'openExternal')
let link = aboutElement.querySelector('.app-update-available-to-install .about-updates-release-notes')
link.click()
let args = shell.openExternal.mostRecentCall.args
expect(shell.openExternal).toHaveBeenCalled()
expect(args[0]).toContain('/v1.2.3')
})
it('executes checkForUpdate() when the check for update button is clicked', () => {
let button = aboutElement.querySelector('.about-update-action-button')
button.click()
expect(atom.autoUpdater.checkForUpdate).toHaveBeenCalled()
})
it('executes restartAndInstallUpdate() when the restart and install button is clicked', async () => {
spyOn(atom.autoUpdater, 'restartAndInstallUpdate')
MockUpdater.finishDownloadingUpdate('42.0.0')
await scheduler.getNextUpdatePromise()
let button = aboutElement.querySelector('.about-update-action-button')
button.click()
expect(atom.autoUpdater.restartAndInstallUpdate).toHaveBeenCalled()
})
it("starts in the same state as atom's AutoUpdateManager", async () => {
atom.autoUpdater.getState.andReturn('downloading')
updateManager.resetState()
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.app-checking-for-updates')).not.toBeVisible()
expect(aboutElement.querySelector('.app-downloading-update')).toBeVisible()
expect(aboutElement.querySelector('.about-update-action-button').disabled).toBe(true)
expect(aboutElement.querySelector('.about-update-action-button').textContent).toBe('Check now')
})
describe('when core.automaticallyUpdate is toggled', () => {
beforeEach(async () => {
expect(atom.config.get('core.automaticallyUpdate')).toBe(true)
atom.autoUpdater.checkForUpdate.reset()
})
it('shows the auto update UI', async () => {
expect(aboutElement.querySelector('.about-auto-updates input').checked).toBe(true)
expect(aboutElement.querySelector('.about-default-update-message')).toBeVisible()
expect(aboutElement.querySelector('.about-default-update-message').textContent).toBe('Atom will check for updates automatically')
atom.config.set('core.automaticallyUpdate', false)
await scheduler.getNextUpdatePromise()
expect(aboutElement.querySelector('.about-auto-updates input').checked).toBe(false)
expect(aboutElement.querySelector('.about-default-update-message')).toBeVisible()
expect(aboutElement.querySelector('.about-default-update-message').textContent).toBe('Automatic updates are disabled please check manually')
})
it('updates config and the UI when the checkbox is used to toggle', async () => {
expect(aboutElement.querySelector('.about-auto-updates input').checked).toBe(true)
aboutElement.querySelector('.about-auto-updates input').click()
await scheduler.getNextUpdatePromise()
expect(atom.config.get('core.automaticallyUpdate')).toBe(false)
expect(aboutElement.querySelector('.about-auto-updates input').checked).toBe(false)
expect(aboutElement.querySelector('.about-default-update-message')).toBeVisible()
expect(aboutElement.querySelector('.about-default-update-message').textContent).toBe('Automatic updates are disabled please check manually')
aboutElement.querySelector('.about-auto-updates input').click()
await scheduler.getNextUpdatePromise()
expect(atom.config.get('core.automaticallyUpdate')).toBe(true)
expect(aboutElement.querySelector('.about-auto-updates input').checked).toBe(true)
expect(aboutElement.querySelector('.about-default-update-message')).toBeVisible()
expect(aboutElement.querySelector('.about-default-update-message').textContent).toBe('Atom will check for updates automatically')
})
describe('checking for updates', function () {
afterEach(() => {
this.updateView = null
})
it('checks for update when the about page is shown', () => {
expect(atom.autoUpdater.checkForUpdate).not.toHaveBeenCalled()
this.updateView = new UpdateView({
updateManager: updateManager,
availableVersion: '9999.0.0',
viewUpdateReleaseNotes: () => {}
})
expect(atom.autoUpdater.checkForUpdate).toHaveBeenCalled()
})
it('does not check for update when the about page is shown and the update manager is not in the idle state', () => {
atom.autoUpdater.getState.andReturn('downloading')
updateManager.resetState()
expect(atom.autoUpdater.checkForUpdate).not.toHaveBeenCalled()
this.updateView = new UpdateView({
updateManager: updateManager,
availableVersion: '9999.0.0',
viewUpdateReleaseNotes: () => {}
})
expect(atom.autoUpdater.checkForUpdate).not.toHaveBeenCalled()
})
it('does not check for update when the about page is shown and auto updates are turned off', () => {
atom.config.set('core.automaticallyUpdate', false)
expect(atom.autoUpdater.checkForUpdate).not.toHaveBeenCalled()
this.updateView = new UpdateView({
updateManager: updateManager,
availableVersion: '9999.0.0',
viewUpdateReleaseNotes: () => {}
})
expect(atom.autoUpdater.checkForUpdate).not.toHaveBeenCalled()
})
})
})
})
})
describe('when the About page is not open and an update is downloaded', () => {
it('should display the new version when it is opened', async () => {
MockUpdater.finishDownloadingUpdate('42.0.0')
jasmine.attachToDOM(workspaceElement)
await atom.workspace.open('atom://about')
aboutElement = workspaceElement.querySelector('.about')
updateManager = main.model.state.updateManager
scheduler = AboutView.getScheduler()
expect(aboutElement.querySelector('.app-update-available-to-install')).toBeVisible()
expect(aboutElement.querySelector('.app-update-available-to-install .about-updates-version').textContent).toBe('42.0.0')
expect(aboutElement.querySelector('.about-update-action-button').disabled).toBe(false)
expect(aboutElement.querySelector('.about-update-action-button').textContent).toBe('Restart and install')
})
})
})