summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfredo Sumaran <alfredo@gitlab.com>2016-11-28 16:43:46 +0000
committerAlfredo Sumaran <alfredo@gitlab.com>2016-11-28 16:43:46 +0000
commitc54827961a6ecefc6cb3361b3978d169e29b5e36 (patch)
tree2652971df42666a68a3c07cf504af3065ce8d075
parentcfb4d65f84898f433771e2deafc36d597db9b8df (diff)
parent31a5ed97a74e250887721413f5a956a93dc2e1b1 (diff)
downloadgitlab-ce-c54827961a6ecefc6cb3361b3978d169e29b5e36.tar.gz
Merge branch 'dynamic-build-fixture' into 'master'
Create dynamic fixture for build_spec ## What does this MR do? Replace `spec/javascripts/fixtures/build.html.haml` by a dynamically created fixture (using `rake teaspoon:fixtures`). ## Why was this MR needed? The existing fixture was not representing the real page. ## What are the relevant issue numbers? #24614 would have been avoided following !6059 See merge request !7589
-rw-r--r--changelogs/unreleased/create-dynamic-fixture-for-build_spec.yml4
-rw-r--r--spec/javascripts/build_spec.js.es6279
-rw-r--r--spec/javascripts/fixtures/build.html.haml62
-rw-r--r--spec/javascripts/fixtures/builds.rb33
-rw-r--r--spec/javascripts/fixtures/issues.rb3
-rw-r--r--spec/javascripts/issue_spec.js2
-rw-r--r--spec/javascripts/spec_helper.js5
-rw-r--r--spec/support/javascript_fixtures_helpers.rb7
8 files changed, 187 insertions, 208 deletions
diff --git a/changelogs/unreleased/create-dynamic-fixture-for-build_spec.yml b/changelogs/unreleased/create-dynamic-fixture-for-build_spec.yml
new file mode 100644
index 00000000000..f0d9ff0c34f
--- /dev/null
+++ b/changelogs/unreleased/create-dynamic-fixture-for-build_spec.yml
@@ -0,0 +1,4 @@
+---
+title: Create dynamic fixture for build_spec
+merge_request: 7589
+author: winniehell
diff --git a/spec/javascripts/build_spec.js.es6 b/spec/javascripts/build_spec.js.es6
index 4208e076e96..d694727880f 100644
--- a/spec/javascripts/build_spec.js.es6
+++ b/spec/javascripts/build_spec.js.es6
@@ -8,184 +8,177 @@
//= require jquery.nicescroll
//= require turbolinks
-(() => {
- describe('Build', () => {
- fixture.preload('build.html');
+describe('Build', () => {
+ const BUILD_URL = `${gl.TEST_HOST}/frontend-fixtures/builds-project/builds/1`;
+ // see spec/factories/ci/builds.rb
+ const BUILD_TRACE = 'BUILD TRACE';
+ // see lib/ci/ansi2html.rb
+ const INITIAL_BUILD_TRACE_STATE = window.btoa(JSON.stringify({
+ offset: BUILD_TRACE.length, n_open_tags: 0, fg_color: null, bg_color: null, style_mask: 0,
+ }));
+
+ fixture.preload('builds/build-with-artifacts.html.raw');
+
+ beforeEach(() => {
+ fixture.load('builds/build-with-artifacts.html.raw');
+ spyOn($, 'ajax');
+ });
+
+ describe('constructor', () => {
+ beforeEach(() => {
+ jasmine.clock().install();
+ });
- beforeEach(function () {
- fixture.load('build.html');
- spyOn($, 'ajax');
+ afterEach(() => {
+ jasmine.clock().uninstall();
});
- describe('constructor', () => {
+ describe('setup', () => {
beforeEach(function () {
- jasmine.clock().install();
+ this.build = new Build();
});
- afterEach(() => {
- jasmine.clock().uninstall();
+ it('copies build options', function () {
+ expect(this.build.pageUrl).toBe(BUILD_URL);
+ expect(this.build.buildUrl).toBe(`${BUILD_URL}.json`);
+ expect(this.build.buildStatus).toBe('success');
+ expect(this.build.buildStage).toBe('test');
+ expect(this.build.state).toBe(INITIAL_BUILD_TRACE_STATE);
});
- describe('setup', function () {
- const removeDate = new Date();
- removeDate.setUTCFullYear(removeDate.getUTCFullYear() + 1);
- // give the test three days to run
- removeDate.setTime(removeDate.getTime() + (3 * 24 * 60 * 60 * 1000));
+ it('only shows the jobs matching the current stage', () => {
+ expect($('.build-job[data-stage="build"]').is(':visible')).toBe(false);
+ expect($('.build-job[data-stage="test"]').is(':visible')).toBe(true);
+ expect($('.build-job[data-stage="deploy"]').is(':visible')).toBe(false);
+ });
- beforeEach(function () {
- const removeDateElement = document.querySelector('.js-artifacts-remove');
- removeDateElement.innerText = removeDate.toString();
+ it('selects the current stage in the build dropdown menu', () => {
+ expect($('.stage-selection').text()).toBe('test');
+ });
- this.build = new Build();
- });
+ it('updates the jobs when the build dropdown changes', () => {
+ $('.stage-item:contains("build")').click();
- it('copies build options', function () {
- expect(this.build.pageUrl).toBe('http://example.com/root/test-build/builds/2');
- expect(this.build.buildUrl).toBe('http://example.com/root/test-build/builds/2.json');
- expect(this.build.buildStatus).toBe('passed');
- expect(this.build.buildStage).toBe('test');
- expect(this.build.state).toBe('buildstate');
- });
+ expect($('.stage-selection').text()).toBe('build');
+ expect($('.build-job[data-stage="build"]').is(':visible')).toBe(true);
+ expect($('.build-job[data-stage="test"]').is(':visible')).toBe(false);
+ expect($('.build-job[data-stage="deploy"]').is(':visible')).toBe(false);
+ });
- it('only shows the jobs matching the current stage', function () {
- expect($('.build-job[data-stage="build"]').is(':visible')).toBe(false);
- expect($('.build-job[data-stage="test"]').is(':visible')).toBe(true);
- expect($('.build-job[data-stage="deploy"]').is(':visible')).toBe(false);
- });
+ it('displays the remove date correctly', () => {
+ const removeDateElement = document.querySelector('.js-artifacts-remove');
+ expect(removeDateElement.innerText.trim()).toBe('1 year');
+ });
+ });
- it('selects the current stage in the build dropdown menu', function () {
- expect($('.stage-selection').text()).toBe('test');
- });
+ describe('initial build trace', () => {
+ beforeEach(() => {
+ new Build();
+ });
- it('updates the jobs when the build dropdown changes', function () {
- $('.stage-item:contains("build")').click();
+ it('displays the initial build trace', () => {
+ expect($.ajax.calls.count()).toBe(1);
+ const [{ url, dataType, success, context }] = $.ajax.calls.argsFor(0);
+ expect(url).toBe(`${BUILD_URL}.json`);
+ expect(dataType).toBe('json');
+ expect(success).toEqual(jasmine.any(Function));
- expect($('.stage-selection').text()).toBe('build');
- expect($('.build-job[data-stage="build"]').is(':visible')).toBe(true);
- expect($('.build-job[data-stage="test"]').is(':visible')).toBe(false);
- expect($('.build-job[data-stage="deploy"]').is(':visible')).toBe(false);
- });
+ success.call(context, { trace_html: '<span>Example</span>', status: 'running' });
- it('displays the remove date correctly', function () {
- const removeDateElement = document.querySelector('.js-artifacts-remove');
- expect(removeDateElement.innerText.trim()).toBe('1 year');
- });
+ expect($('#build-trace .js-build-output').text()).toMatch(/Example/);
});
- describe('initial build trace', function () {
- beforeEach(function () {
- new Build();
- });
+ it('removes the spinner', () => {
+ const [{ success, context }] = $.ajax.calls.argsFor(0);
+ success.call(context, { trace_html: '<span>Example</span>', status: 'success' });
- it('displays the initial build trace', function () {
- expect($.ajax.calls.count()).toBe(1);
- const [{ url, dataType, success, context }] = $.ajax.calls.argsFor(0);
- expect(url).toBe('http://example.com/root/test-build/builds/2.json');
- expect(dataType).toBe('json');
- expect(success).toEqual(jasmine.any(Function));
+ expect($('.js-build-refresh').length).toBe(0);
+ });
+ });
- success.call(context, { trace_html: '<span>Example</span>', status: 'running' });
+ describe('running build', () => {
+ beforeEach(function () {
+ $('.js-build-options').data('buildStatus', 'running');
+ this.build = new Build();
+ spyOn(this.build, 'location').and.returnValue(BUILD_URL);
+ });
- expect($('#build-trace .js-build-output').text()).toMatch(/Example/);
+ it('updates the build trace on an interval', function () {
+ jasmine.clock().tick(4001);
+
+ expect($.ajax.calls.count()).toBe(2);
+ let [{ url, dataType, success, context }] = $.ajax.calls.argsFor(1);
+ expect(url).toBe(
+ `${BUILD_URL}/trace.json?state=${encodeURIComponent(INITIAL_BUILD_TRACE_STATE)}`
+ );
+ expect(dataType).toBe('json');
+ expect(success).toEqual(jasmine.any(Function));
+
+ success.call(context, {
+ html: '<span>Update<span>',
+ status: 'running',
+ state: 'newstate',
+ append: true,
});
- it('removes the spinner', function () {
- const [{ success, context }] = $.ajax.calls.argsFor(0);
- success.call(context, { trace_html: '<span>Example</span>', status: 'success' });
+ expect($('#build-trace .js-build-output').text()).toMatch(/Update/);
+ expect(this.build.state).toBe('newstate');
- expect($('.js-build-refresh').length).toBe(0);
+ jasmine.clock().tick(4001);
+
+ expect($.ajax.calls.count()).toBe(3);
+ [{ url, dataType, success, context }] = $.ajax.calls.argsFor(2);
+ expect(url).toBe(`${BUILD_URL}/trace.json?state=newstate`);
+ expect(dataType).toBe('json');
+ expect(success).toEqual(jasmine.any(Function));
+
+ success.call(context, {
+ html: '<span>More</span>',
+ status: 'running',
+ state: 'finalstate',
+ append: true,
});
+
+ expect($('#build-trace .js-build-output').text()).toMatch(/UpdateMore/);
+ expect(this.build.state).toBe('finalstate');
});
- describe('running build', function () {
- beforeEach(function () {
- $('.js-build-options').data('buildStatus', 'running');
- this.build = new Build();
- spyOn(this.build, 'location')
- .and.returnValue('http://example.com/root/test-build/builds/2');
+ it('replaces the entire build trace', () => {
+ jasmine.clock().tick(4001);
+ let [{ success, context }] = $.ajax.calls.argsFor(1);
+ success.call(context, {
+ html: '<span>Update</span>',
+ status: 'running',
+ append: true,
});
- it('updates the build trace on an interval', function () {
- jasmine.clock().tick(4001);
-
- expect($.ajax.calls.count()).toBe(2);
- let [{ url, dataType, success, context }] = $.ajax.calls.argsFor(1);
- expect(url).toBe(
- 'http://example.com/root/test-build/builds/2/trace.json?state=buildstate'
- );
- expect(dataType).toBe('json');
- expect(success).toEqual(jasmine.any(Function));
-
- success.call(context, {
- html: '<span>Update<span>',
- status: 'running',
- state: 'newstate',
- append: true,
- });
-
- expect($('#build-trace .js-build-output').text()).toMatch(/Update/);
- expect(this.build.state).toBe('newstate');
-
- jasmine.clock().tick(4001);
-
- expect($.ajax.calls.count()).toBe(3);
- [{ url, dataType, success, context }] = $.ajax.calls.argsFor(2);
- expect(url).toBe(
- 'http://example.com/root/test-build/builds/2/trace.json?state=newstate'
- );
- expect(dataType).toBe('json');
- expect(success).toEqual(jasmine.any(Function));
-
- success.call(context, {
- html: '<span>More</span>',
- status: 'running',
- state: 'finalstate',
- append: true,
- });
-
- expect($('#build-trace .js-build-output').text()).toMatch(/UpdateMore/);
- expect(this.build.state).toBe('finalstate');
- });
+ expect($('#build-trace .js-build-output').text()).toMatch(/Update/);
- it('replaces the entire build trace', function () {
- jasmine.clock().tick(4001);
- let [{ success, context }] = $.ajax.calls.argsFor(1);
- success.call(context, {
- html: '<span>Update</span>',
- status: 'running',
- append: true,
- });
-
- expect($('#build-trace .js-build-output').text()).toMatch(/Update/);
-
- jasmine.clock().tick(4001);
- [{ success, context }] = $.ajax.calls.argsFor(2);
- success.call(context, {
- html: '<span>Different</span>',
- status: 'running',
- append: false,
- });
-
- expect($('#build-trace .js-build-output').text()).not.toMatch(/Update/);
- expect($('#build-trace .js-build-output').text()).toMatch(/Different/);
+ jasmine.clock().tick(4001);
+ [{ success, context }] = $.ajax.calls.argsFor(2);
+ success.call(context, {
+ html: '<span>Different</span>',
+ status: 'running',
+ append: false,
});
- it('reloads the page when the build is done', function () {
- spyOn(Turbolinks, 'visit');
+ expect($('#build-trace .js-build-output').text()).not.toMatch(/Update/);
+ expect($('#build-trace .js-build-output').text()).toMatch(/Different/);
+ });
- jasmine.clock().tick(4001);
- const [{ success, context }] = $.ajax.calls.argsFor(1);
- success.call(context, {
- html: '<span>Final</span>',
- status: 'passed',
- append: true,
- });
+ it('reloads the page when the build is done', () => {
+ spyOn(Turbolinks, 'visit');
- expect(Turbolinks.visit).toHaveBeenCalledWith(
- 'http://example.com/root/test-build/builds/2'
- );
+ jasmine.clock().tick(4001);
+ const [{ success, context }] = $.ajax.calls.argsFor(1);
+ success.call(context, {
+ html: '<span>Final</span>',
+ status: 'passed',
+ append: true,
});
+
+ expect(Turbolinks.visit).toHaveBeenCalledWith(BUILD_URL);
});
});
});
-})();
+});
diff --git a/spec/javascripts/fixtures/build.html.haml b/spec/javascripts/fixtures/build.html.haml
deleted file mode 100644
index 06b49516e5c..00000000000
--- a/spec/javascripts/fixtures/build.html.haml
+++ /dev/null
@@ -1,62 +0,0 @@
-.build-page
- .prepend-top-default
- .autoscroll-container
- %button.btn.btn-success.btn-sm#autoscroll-button{:type => "button", :data => {:state => 'disabled'}} enable autoscroll
- #js-build-scroll.scroll-controls
- %a.btn{href: '#build-trace'}
- %i.fa.fa-angle-up
- %a.btn{href: '#down-build-trace'}
- %i.fa.fa-angle-down
- %pre.build-trace#build-trace
- %code.bash.js-build-output
- %i.fa.fa-refresh.fa-spin.js-build-refresh
-
-%aside.right-sidebar.right-sidebar-expanded.build-sidebar.js-build-sidebar
- .block.build-sidebar-header.visible-xs-block.visible-sm-block.append-bottom-default
- Build
- %strong #1
- %a.gutter-toggle.pull-right.js-sidebar-build-toggle{ href: "#" }
- %i.fa.fa-angle-double-right
- .blocks-container
- .dropdown.build-dropdown
- .title Stage
- %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'}
- %span.stage-selection More
- %i.fa.fa-caret-down
- %ul.dropdown-menu
- %li
- %a.stage-item build
- %li
- %a.stage-item test
- %li
- %a.stage-item deploy
- .builds-container
- .build-job{data: {stage: 'build'}}
- %a{href: 'http://example.com/root/test-build/builds/1'}
- %i.fa.fa-check
- %i.fa.fa-check-circle-o
- %span
- Setup
- .build-job{data: {stage: 'test'}}
- %a{href: 'http://example.com/root/test-build/builds/2'}
- %i.fa.fa-check
- %i.fa.fa-check-circle-o
- %span
- Tests
- .build-job{data: {stage: 'deploy'}}
- %a{href: 'http://example.com/root/test-build/builds/3'}
- %i.fa.fa-check
- %i.fa.fa-check-circle-o
- %span
- Deploy
-
-.js-build-options{ data: { page_url: 'http://example.com/root/test-build/builds/2',
- build_url: 'http://example.com/root/test-build/builds/2.json',
- build_status: 'passed',
- build_stage: 'test',
- log_state: 'buildstate' }}
-
-%p.build-detail-row
- The artifacts will be removed in
- %span.js-artifacts-remove
- 2016-12-19 09:02:12 UTC
diff --git a/spec/javascripts/fixtures/builds.rb b/spec/javascripts/fixtures/builds.rb
new file mode 100644
index 00000000000..978e25a1c32
--- /dev/null
+++ b/spec/javascripts/fixtures/builds.rb
@@ -0,0 +1,33 @@
+require 'spec_helper'
+
+describe Projects::BuildsController, '(JavaScript fixtures)', type: :controller do
+ include JavaScriptFixturesHelpers
+
+ let(:admin) { create(:admin) }
+ let(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
+ let(:project) { create(:project_empty_repo, namespace: namespace, path: 'builds-project') }
+ let(:pipeline) { create(:ci_empty_pipeline, project: project) }
+ let!(:build_with_artifacts) { create(:ci_build, :success, :artifacts, :trace, pipeline: pipeline, stage: 'test', artifacts_expire_at: Time.now + 18.months) }
+ let!(:failed_build) { create(:ci_build, :failed, pipeline: pipeline, stage: 'build') }
+ let!(:pending_build) { create(:ci_build, :pending, pipeline: pipeline, stage: 'deploy') }
+
+ render_views
+
+ before(:all) do
+ clean_frontend_fixtures('builds/')
+ end
+
+ before(:each) do
+ sign_in(admin)
+ end
+
+ it 'builds/build-with-artifacts.html.raw' do |example|
+ get :show,
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ id: build_with_artifacts.to_param
+
+ expect(response).to be_success
+ store_frontend_fixture(response, example.description)
+ end
+end
diff --git a/spec/javascripts/fixtures/issues.rb b/spec/javascripts/fixtures/issues.rb
index d95eb851421..c10784fe5ae 100644
--- a/spec/javascripts/fixtures/issues.rb
+++ b/spec/javascripts/fixtures/issues.rb
@@ -4,7 +4,8 @@ describe Projects::IssuesController, '(JavaScript fixtures)', type: :controller
include JavaScriptFixturesHelpers
let(:admin) { create(:admin) }
- let(:project) { create(:project_empty_repo) }
+ let(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
+ let(:project) { create(:project_empty_repo, namespace: namespace, path: 'issues-project') }
render_views
diff --git a/spec/javascripts/issue_spec.js b/spec/javascripts/issue_spec.js
index beef46122ab..14af6644de1 100644
--- a/spec/javascripts/issue_spec.js
+++ b/spec/javascripts/issue_spec.js
@@ -74,7 +74,7 @@
it('submits an ajax request on tasklist:changed', function() {
spyOn(jQuery, 'ajax').and.callFake(function(req) {
expect(req.type).toBe('PATCH');
- expect(req.url).toBe('https://fixture.invalid/namespace3/project3/issues/1.json');
+ expect(req.url).toBe(gl.TEST_HOST + '/frontend-fixtures/issues-project/issues/1.json'); // eslint-disable-line prefer-template
expect(req.data.issue.description).not.toBe(null);
});
diff --git a/spec/javascripts/spec_helper.js b/spec/javascripts/spec_helper.js
index 8a64de4dd43..831dfada952 100644
--- a/spec/javascripts/spec_helper.js
+++ b/spec/javascripts/spec_helper.js
@@ -41,3 +41,8 @@
}).call(this);
+
+// defined in ActionDispatch::TestRequest
+// see https://github.com/rails/rails/blob/v4.2.7.1/actionpack/lib/action_dispatch/testing/test_request.rb#L7
+window.gl = window.gl || {};
+gl.TEST_HOST = 'http://test.host';
diff --git a/spec/support/javascript_fixtures_helpers.rb b/spec/support/javascript_fixtures_helpers.rb
index adc3f48b434..99e98eebdb4 100644
--- a/spec/support/javascript_fixtures_helpers.rb
+++ b/spec/support/javascript_fixtures_helpers.rb
@@ -1,3 +1,4 @@
+require 'action_dispatch/testing/test_request'
require 'fileutils'
require 'gitlab/popen'
@@ -30,13 +31,17 @@ module JavaScriptFixturesHelpers
if response_mime_type.html?
doc = Nokogiri::HTML::DocumentFragment.parse(fixture)
+ link_tags = doc.css('link')
+ link_tags.remove
+
scripts = doc.css('script')
scripts.remove
fixture = doc.to_html
# replace relative links
- fixture.gsub!(%r{="/}, '="https://fixture.invalid/')
+ test_host = ActionDispatch::TestRequest::DEFAULT_ENV['HTTP_HOST']
+ fixture.gsub!(%r{="/}, "=\"http://#{test_host}/")
end
FileUtils.mkdir_p(File.dirname(fixture_file_name))