summaryrefslogtreecommitdiff
path: root/spec/javascripts
diff options
context:
space:
mode:
Diffstat (limited to 'spec/javascripts')
-rw-r--r--spec/javascripts/clusters_spec.js79
-rw-r--r--spec/javascripts/fixtures/clusters.rb34
-rw-r--r--spec/javascripts/repo/components/repo_file_spec.js16
-rw-r--r--spec/javascripts/repo/components/repo_sidebar_spec.js60
-rw-r--r--spec/javascripts/sidebar/lock/edit_form_buttons_spec.js36
-rw-r--r--spec/javascripts/sidebar/lock/edit_form_spec.js41
-rw-r--r--spec/javascripts/sidebar/lock/lock_issue_sidebar_spec.js71
-rw-r--r--spec/javascripts/vue_mr_widget/services/mr_widget_service_spec.js1
-rw-r--r--spec/javascripts/vue_shared/components/issue/confidential_issue_warning_spec.js20
-rw-r--r--spec/javascripts/vue_shared/components/issue/issue_warning_spec.js46
10 files changed, 369 insertions, 35 deletions
diff --git a/spec/javascripts/clusters_spec.js b/spec/javascripts/clusters_spec.js
new file mode 100644
index 00000000000..eb1cd6eb804
--- /dev/null
+++ b/spec/javascripts/clusters_spec.js
@@ -0,0 +1,79 @@
+import Clusters from '~/clusters';
+
+describe('Clusters', () => {
+ let cluster;
+ preloadFixtures('clusters/show_cluster.html.raw');
+
+ beforeEach(() => {
+ loadFixtures('clusters/show_cluster.html.raw');
+ cluster = new Clusters();
+ });
+
+ describe('toggle', () => {
+ it('should update the button and the input field on click', () => {
+ cluster.toggleButton.click();
+
+ expect(
+ cluster.toggleButton.classList,
+ ).not.toContain('checked');
+
+ expect(
+ cluster.toggleInput.getAttribute('value'),
+ ).toEqual('false');
+ });
+ });
+
+ describe('updateContainer', () => {
+ describe('when creating cluster', () => {
+ it('should show the creating container', () => {
+ cluster.updateContainer('creating');
+
+ expect(
+ cluster.creatingContainer.classList.contains('hidden'),
+ ).toBeFalsy();
+ expect(
+ cluster.successContainer.classList.contains('hidden'),
+ ).toBeTruthy();
+ expect(
+ cluster.errorContainer.classList.contains('hidden'),
+ ).toBeTruthy();
+ });
+ });
+
+ describe('when cluster is created', () => {
+ it('should show the success container', () => {
+ cluster.updateContainer('created');
+
+ expect(
+ cluster.creatingContainer.classList.contains('hidden'),
+ ).toBeTruthy();
+ expect(
+ cluster.successContainer.classList.contains('hidden'),
+ ).toBeFalsy();
+ expect(
+ cluster.errorContainer.classList.contains('hidden'),
+ ).toBeTruthy();
+ });
+ });
+
+ describe('when cluster has error', () => {
+ it('should show the error container', () => {
+ cluster.updateContainer('errored', 'this is an error');
+
+ expect(
+ cluster.creatingContainer.classList.contains('hidden'),
+ ).toBeTruthy();
+ expect(
+ cluster.successContainer.classList.contains('hidden'),
+ ).toBeTruthy();
+ expect(
+ cluster.errorContainer.classList.contains('hidden'),
+ ).toBeFalsy();
+
+ expect(
+ cluster.errorReasonContainer.textContent,
+ ).toContain('this is an error');
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/fixtures/clusters.rb b/spec/javascripts/fixtures/clusters.rb
new file mode 100644
index 00000000000..5774f36f026
--- /dev/null
+++ b/spec/javascripts/fixtures/clusters.rb
@@ -0,0 +1,34 @@
+require 'spec_helper'
+
+describe Projects::ClustersController, '(JavaScript fixtures)', type: :controller do
+ include JavaScriptFixturesHelpers
+
+ let(:admin) { create(:admin) }
+ let(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
+ let(:project) { create(:project, :repository, namespace: namespace) }
+ let(:cluster) { project.create_cluster!(gcp_cluster_name: "gke-test-creation-1", gcp_project_id: 'gitlab-internal-153318', gcp_cluster_zone: 'us-central1-a', gcp_cluster_size: '1', project_namespace: 'aaa', gcp_machine_type: 'n1-standard-1')}
+
+ render_views
+
+ before(:all) do
+ clean_frontend_fixtures('clusters/')
+ end
+
+ before do
+ sign_in(admin)
+ end
+
+ after do
+ remove_repository(project)
+ end
+
+ it 'clusters/show_cluster.html.raw' do |example|
+ get :show,
+ namespace_id: project.namespace.to_param,
+ project_id: project,
+ id: cluster
+
+ expect(response).to be_success
+ store_frontend_fixture(response, example.description)
+ end
+end
diff --git a/spec/javascripts/repo/components/repo_file_spec.js b/spec/javascripts/repo/components/repo_file_spec.js
index f15633bd8b9..620b604f404 100644
--- a/spec/javascripts/repo/components/repo_file_spec.js
+++ b/spec/javascripts/repo/components/repo_file_spec.js
@@ -29,15 +29,17 @@ describe('RepoFile', () => {
}).$mount();
}
- beforeEach(() => {
- spyOn(repoFile.mixins[0].methods, 'timeFormated').and.returnValue(updated);
- });
-
it('renders link, icon, name and last commit details', () => {
- const vm = createComponent({
- file,
- activeFile,
+ const RepoFile = Vue.extend(repoFile);
+ const vm = new RepoFile({
+ propsData: {
+ file,
+ activeFile,
+ },
});
+ spyOn(vm, 'timeFormated').and.returnValue(updated);
+ vm.$mount();
+
const name = vm.$el.querySelector('.repo-file-name');
const fileIcon = vm.$el.querySelector('.file-icon');
diff --git a/spec/javascripts/repo/components/repo_sidebar_spec.js b/spec/javascripts/repo/components/repo_sidebar_spec.js
index 23c10ea022e..35d2b37ac2a 100644
--- a/spec/javascripts/repo/components/repo_sidebar_spec.js
+++ b/spec/javascripts/repo/components/repo_sidebar_spec.js
@@ -5,18 +5,26 @@ import RepoStore from '~/repo/stores/repo_store';
import repoSidebar from '~/repo/components/repo_sidebar.vue';
describe('RepoSidebar', () => {
+ let vm;
+
function createComponent() {
const RepoSidebar = Vue.extend(repoSidebar);
return new RepoSidebar().$mount();
}
+ afterEach(() => {
+ vm.$destroy();
+ });
+
it('renders a sidebar', () => {
RepoStore.files = [{
id: 0,
}];
RepoStore.openedFiles = [];
- const vm = createComponent();
+ RepoStore.isRoot = false;
+
+ vm = createComponent();
const thead = vm.$el.querySelector('thead');
const tbody = vm.$el.querySelector('tbody');
@@ -35,7 +43,7 @@ describe('RepoSidebar', () => {
RepoStore.openedFiles = [{
id: 0,
}];
- const vm = createComponent();
+ vm = createComponent();
expect(vm.$el.classList.contains('sidebar-mini')).toBeTruthy();
expect(vm.$el.querySelector('thead')).toBeFalsy();
@@ -47,7 +55,7 @@ describe('RepoSidebar', () => {
tree: true,
};
RepoStore.files = [];
- const vm = createComponent();
+ vm = createComponent();
expect(vm.$el.querySelectorAll('tbody .loading-file').length).toEqual(5);
});
@@ -57,7 +65,7 @@ describe('RepoSidebar', () => {
id: 0,
}];
RepoStore.isRoot = true;
- const vm = createComponent();
+ vm = createComponent();
expect(vm.$el.querySelector('tbody .prev-directory')).toBeTruthy();
});
@@ -72,7 +80,7 @@ describe('RepoSidebar', () => {
};
RepoStore.files = [file1];
RepoStore.isRoot = true;
- const vm = createComponent();
+ vm = createComponent();
vm.fileClicked(file1);
@@ -87,7 +95,7 @@ describe('RepoSidebar', () => {
spyOn(Helper, 'getFileFromPath').and.returnValue(file);
spyOn(RepoStore, 'setActiveFiles');
- const vm = createComponent();
+ vm = createComponent();
vm.fileClicked(file);
expect(RepoStore.setActiveFiles).toHaveBeenCalledWith(file);
@@ -103,7 +111,7 @@ describe('RepoSidebar', () => {
};
RepoStore.files = [file1];
RepoStore.isRoot = true;
- const vm = createComponent();
+ vm = createComponent();
vm.fileClicked(file1);
@@ -114,12 +122,48 @@ describe('RepoSidebar', () => {
describe('goToPreviousDirectoryClicked', () => {
it('should hide files in directory if already open', () => {
const prevUrl = 'foo/bar';
- const vm = createComponent();
+ vm = createComponent();
vm.goToPreviousDirectoryClicked(prevUrl);
expect(RepoService.url).toEqual(prevUrl);
});
});
+
+ describe('back button', () => {
+ const file1 = {
+ id: 1,
+ url: 'file1',
+ };
+ const file2 = {
+ id: 2,
+ url: 'file2',
+ };
+ RepoStore.files = [file1, file2];
+ RepoStore.openedFiles = [file1, file2];
+ RepoStore.isRoot = true;
+
+ vm = createComponent();
+ vm.fileClicked(file1);
+
+ it('render previous file when using back button', () => {
+ spyOn(Helper, 'getContent').and.callThrough();
+
+ vm.fileClicked(file2);
+ expect(Helper.getContent).toHaveBeenCalledWith(file2);
+ Helper.getContent.calls.reset();
+
+ history.pushState({
+ key: Math.random(),
+ }, '', file1.url);
+ const popEvent = document.createEvent('Event');
+ popEvent.initEvent('popstate', true, true);
+ window.dispatchEvent(popEvent);
+
+ expect(Helper.getContent.calls.mostRecent().args[0].url).toContain(file1.url);
+
+ window.history.pushState({}, null, '/');
+ });
+ });
});
});
diff --git a/spec/javascripts/sidebar/lock/edit_form_buttons_spec.js b/spec/javascripts/sidebar/lock/edit_form_buttons_spec.js
new file mode 100644
index 00000000000..b0ea8ae0206
--- /dev/null
+++ b/spec/javascripts/sidebar/lock/edit_form_buttons_spec.js
@@ -0,0 +1,36 @@
+import Vue from 'vue';
+import editFormButtons from '~/sidebar/components/lock/edit_form_buttons.vue';
+import mountComponent from '../../helpers/vue_mount_component_helper';
+
+describe('EditFormButtons', () => {
+ let vm1;
+ let vm2;
+
+ beforeEach(() => {
+ const Component = Vue.extend(editFormButtons);
+ const toggleForm = () => { };
+ const updateLockedAttribute = () => { };
+
+ vm1 = mountComponent(Component, {
+ isLocked: true,
+ toggleForm,
+ updateLockedAttribute,
+ });
+
+ vm2 = mountComponent(Component, {
+ isLocked: false,
+ toggleForm,
+ updateLockedAttribute,
+ });
+ });
+
+ it('renders unlock or lock text based on locked state', () => {
+ expect(
+ vm1.$el.innerHTML.includes('Unlock'),
+ ).toBe(true);
+
+ expect(
+ vm2.$el.innerHTML.includes('Lock'),
+ ).toBe(true);
+ });
+});
diff --git a/spec/javascripts/sidebar/lock/edit_form_spec.js b/spec/javascripts/sidebar/lock/edit_form_spec.js
new file mode 100644
index 00000000000..7abd6997a18
--- /dev/null
+++ b/spec/javascripts/sidebar/lock/edit_form_spec.js
@@ -0,0 +1,41 @@
+import Vue from 'vue';
+import editForm from '~/sidebar/components/lock/edit_form.vue';
+
+describe('EditForm', () => {
+ let vm1;
+ let vm2;
+
+ beforeEach(() => {
+ const Component = Vue.extend(editForm);
+ const toggleForm = () => { };
+ const updateLockedAttribute = () => { };
+
+ vm1 = new Component({
+ propsData: {
+ isLocked: true,
+ toggleForm,
+ updateLockedAttribute,
+ issuableType: 'issue',
+ },
+ }).$mount();
+
+ vm2 = new Component({
+ propsData: {
+ isLocked: false,
+ toggleForm,
+ updateLockedAttribute,
+ issuableType: 'merge_request',
+ },
+ }).$mount();
+ });
+
+ it('renders on the appropriate warning text', () => {
+ expect(
+ vm1.$el.innerHTML.includes('Unlock this issue?'),
+ ).toBe(true);
+
+ expect(
+ vm2.$el.innerHTML.includes('Lock this merge request?'),
+ ).toBe(true);
+ });
+});
diff --git a/spec/javascripts/sidebar/lock/lock_issue_sidebar_spec.js b/spec/javascripts/sidebar/lock/lock_issue_sidebar_spec.js
new file mode 100644
index 00000000000..696fca516bc
--- /dev/null
+++ b/spec/javascripts/sidebar/lock/lock_issue_sidebar_spec.js
@@ -0,0 +1,71 @@
+import Vue from 'vue';
+import lockIssueSidebar from '~/sidebar/components/lock/lock_issue_sidebar.vue';
+
+describe('LockIssueSidebar', () => {
+ let vm1;
+ let vm2;
+
+ beforeEach(() => {
+ const Component = Vue.extend(lockIssueSidebar);
+
+ const mediator = {
+ service: {
+ update: Promise.resolve(true),
+ },
+
+ store: {
+ isLockDialogOpen: false,
+ },
+ };
+
+ vm1 = new Component({
+ propsData: {
+ isLocked: true,
+ isEditable: true,
+ mediator,
+ issuableType: 'issue',
+ },
+ }).$mount();
+
+ vm2 = new Component({
+ propsData: {
+ isLocked: false,
+ isEditable: false,
+ mediator,
+ issuableType: 'merge_request',
+ },
+ }).$mount();
+ });
+
+ it('shows if locked and/or editable', () => {
+ expect(
+ vm1.$el.innerHTML.includes('Edit'),
+ ).toBe(true);
+
+ expect(
+ vm1.$el.innerHTML.includes('Locked'),
+ ).toBe(true);
+
+ expect(
+ vm2.$el.innerHTML.includes('Unlocked'),
+ ).toBe(true);
+ });
+
+ it('displays the edit form when editable', (done) => {
+ expect(vm1.isLockDialogOpen).toBe(false);
+
+ vm1.$el.querySelector('.lock-edit').click();
+
+ expect(vm1.isLockDialogOpen).toBe(true);
+
+ vm1.$nextTick(() => {
+ expect(
+ vm1.$el
+ .innerHTML
+ .includes('Unlock this issue?'),
+ ).toBe(true);
+
+ done();
+ });
+ });
+});
diff --git a/spec/javascripts/vue_mr_widget/services/mr_widget_service_spec.js b/spec/javascripts/vue_mr_widget/services/mr_widget_service_spec.js
index b63633c03b8..e667b4b3677 100644
--- a/spec/javascripts/vue_mr_widget/services/mr_widget_service_spec.js
+++ b/spec/javascripts/vue_mr_widget/services/mr_widget_service_spec.js
@@ -31,6 +31,7 @@ describe('MRWidgetService', () => {
});
it('should have methods defined', () => {
+ window.history.pushState({}, null, '/');
const service = new MRWidgetService(mr);
expect(service.merge()).toBeDefined();
diff --git a/spec/javascripts/vue_shared/components/issue/confidential_issue_warning_spec.js b/spec/javascripts/vue_shared/components/issue/confidential_issue_warning_spec.js
deleted file mode 100644
index 6df08f3ebe7..00000000000
--- a/spec/javascripts/vue_shared/components/issue/confidential_issue_warning_spec.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import Vue from 'vue';
-import confidentialIssue from '~/vue_shared/components/issue/confidential_issue_warning.vue';
-
-describe('Confidential Issue Warning Component', () => {
- let vm;
-
- beforeEach(() => {
- const Component = Vue.extend(confidentialIssue);
- vm = new Component().$mount();
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('should render confidential issue warning information', () => {
- expect(vm.$el.querySelector('i').className).toEqual('fa fa-eye-slash');
- expect(vm.$el.querySelector('span').textContent.trim()).toEqual('This is a confidential issue. Your comment will not be visible to the public.');
- });
-});
diff --git a/spec/javascripts/vue_shared/components/issue/issue_warning_spec.js b/spec/javascripts/vue_shared/components/issue/issue_warning_spec.js
new file mode 100644
index 00000000000..2cf4d8e00ed
--- /dev/null
+++ b/spec/javascripts/vue_shared/components/issue/issue_warning_spec.js
@@ -0,0 +1,46 @@
+import Vue from 'vue';
+import issueWarning from '~/vue_shared/components/issue/issue_warning.vue';
+import mountComponent from '../../../helpers/vue_mount_component_helper';
+
+const IssueWarning = Vue.extend(issueWarning);
+
+function formatWarning(string) {
+ // Replace newlines with a space then replace multiple spaces with one space
+ return string.trim().replace(/\n/g, ' ').replace(/\s\s+/g, ' ');
+}
+
+describe('Issue Warning Component', () => {
+ describe('isLocked', () => {
+ it('should render locked issue warning information', () => {
+ const vm = mountComponent(IssueWarning, {
+ isLocked: true,
+ });
+
+ expect(vm.$el.querySelector('i').className).toEqual('fa icon fa-lock');
+ expect(formatWarning(vm.$el.querySelector('span').textContent)).toEqual('This issue is locked. Only project members can comment.');
+ });
+ });
+
+ describe('isConfidential', () => {
+ it('should render confidential issue warning information', () => {
+ const vm = mountComponent(IssueWarning, {
+ isConfidential: true,
+ });
+
+ expect(vm.$el.querySelector('i').className).toEqual('fa icon fa-eye-slash');
+ expect(formatWarning(vm.$el.querySelector('span').textContent)).toEqual('This is a confidential issue. Your comment will not be visible to the public.');
+ });
+ });
+
+ describe('isLocked and isConfidential', () => {
+ it('should render locked and confidential issue warning information', () => {
+ const vm = mountComponent(IssueWarning, {
+ isLocked: true,
+ isConfidential: true,
+ });
+
+ expect(vm.$el.querySelector('i')).toBeFalsy();
+ expect(formatWarning(vm.$el.querySelector('span').textContent)).toEqual('This issue is confidential and locked. People without permission will never get a notification and won\'t be able to comment.');
+ });
+ });
+});