diff options
author | Alfredo Sumaran <alfredo@gitlab.com> | 2016-11-28 16:43:46 +0000 |
---|---|---|
committer | Alfredo Sumaran <alfredo@gitlab.com> | 2016-11-28 16:43:46 +0000 |
commit | c54827961a6ecefc6cb3361b3978d169e29b5e36 (patch) | |
tree | 2652971df42666a68a3c07cf504af3065ce8d075 | |
parent | cfb4d65f84898f433771e2deafc36d597db9b8df (diff) | |
parent | 31a5ed97a74e250887721413f5a956a93dc2e1b1 (diff) | |
download | gitlab-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.yml | 4 | ||||
-rw-r--r-- | spec/javascripts/build_spec.js.es6 | 279 | ||||
-rw-r--r-- | spec/javascripts/fixtures/build.html.haml | 62 | ||||
-rw-r--r-- | spec/javascripts/fixtures/builds.rb | 33 | ||||
-rw-r--r-- | spec/javascripts/fixtures/issues.rb | 3 | ||||
-rw-r--r-- | spec/javascripts/issue_spec.js | 2 | ||||
-rw-r--r-- | spec/javascripts/spec_helper.js | 5 | ||||
-rw-r--r-- | spec/support/javascript_fixtures_helpers.rb | 7 |
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)) |