From 0f060bf4fccc3119dc4b7d6e296c2f0fc994bb4e Mon Sep 17 00:00:00 2001
From: winniehell <git@winniehell.de>
Date: Mon, 29 Aug 2016 18:18:59 +0200
Subject: [PATCH] Replace static issue fixtures by script (!6059)

---
 .gitlab-ci.yml                                |  2 +-
 CHANGELOG.md                                  |  1 +
 lib/tasks/teaspoon.rake                       | 23 ++++++++++
 spec/javascripts/fixtures/.gitignore          |  1 +
 spec/javascripts/fixtures/issues.rb           | 44 ++++++++++++++++++
 .../fixtures/issues_show.html.haml            | 23 ----------
 spec/javascripts/issue_spec.js                | 35 ++++++++-------
 spec/spec_helper.rb                           |  2 +-
 spec/support/javascript_fixtures_helpers.rb   | 45 +++++++++++++++++++
 9 files changed, 134 insertions(+), 42 deletions(-)
 create mode 100644 lib/tasks/teaspoon.rake
 create mode 100644 spec/javascripts/fixtures/.gitignore
 create mode 100644 spec/javascripts/fixtures/issues.rb
 delete mode 100644 spec/javascripts/fixtures/issues_show.html.haml
 create mode 100644 spec/support/javascript_fixtures_helpers.rb

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 3f315550536..d04069df885 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -249,7 +249,7 @@ teaspoon:
     - curl --silent --location https://deb.nodesource.com/setup_6.x | bash -
     - apt-get install --assume-yes nodejs
     - npm install --global istanbul
-    - teaspoon
+    - rake teaspoon
   artifacts:
     name: coverage-javascript
     expire_in: 31d
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5bcbd309f19..a8eb0bd33c9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -154,6 +154,7 @@ Please view this file on the master branch, on stable branches it's out of date.
   - Only update issuable labels if they have been changed
   - Take filters in account in issuable counters. !6496
   - Use custom Ruby images to test builds (registry.dev.gitlab.org/gitlab/gitlab-build-images:*)
+  - Replace static issue fixtures by script !6059 (winniehell)
   - Append issue template to existing description !6149 (Joseph Frazier)
   - Trending projects now only show public projects and the list of projects is cached for a day
   - Memoize Gitlab Shell's secret token (!6599, Justin DiPierro)
diff --git a/lib/tasks/teaspoon.rake b/lib/tasks/teaspoon.rake
new file mode 100644
index 00000000000..156fa90537d
--- /dev/null
+++ b/lib/tasks/teaspoon.rake
@@ -0,0 +1,23 @@
+Rake::Task['teaspoon'].clear if Rake::Task.task_defined?('teaspoon')
+
+namespace :teaspoon do
+  desc 'GitLab | Teaspoon | Generate fixtures for JavaScript tests'
+  RSpec::Core::RakeTask.new(:fixtures) do |t|
+    ENV['NO_KNAPSACK'] = 'true'
+    t.pattern = 'spec/javascripts/fixtures/*.rb'
+    t.rspec_opts = '--format documentation'
+  end
+
+  desc 'GitLab | Teaspoon | Run JavaScript tests'
+  task :tests do
+    require "teaspoon/console"
+    options = {}
+    abort('rake teaspoon:tests failed') if Teaspoon::Console.new(options).failures?
+  end
+end
+
+desc 'GitLab | Teaspoon | Shortcut for teaspoon:fixtures and teaspoon:tests'
+task :teaspoon do
+  Rake::Task['teaspoon:fixtures'].invoke
+  Rake::Task['teaspoon:tests'].invoke
+end
diff --git a/spec/javascripts/fixtures/.gitignore b/spec/javascripts/fixtures/.gitignore
new file mode 100644
index 00000000000..009b68d5d1c
--- /dev/null
+++ b/spec/javascripts/fixtures/.gitignore
@@ -0,0 +1 @@
+*.html.raw
diff --git a/spec/javascripts/fixtures/issues.rb b/spec/javascripts/fixtures/issues.rb
new file mode 100644
index 00000000000..d95eb851421
--- /dev/null
+++ b/spec/javascripts/fixtures/issues.rb
@@ -0,0 +1,44 @@
+require 'spec_helper'
+
+describe Projects::IssuesController, '(JavaScript fixtures)', type: :controller do
+  include JavaScriptFixturesHelpers
+
+  let(:admin) { create(:admin) }
+  let(:project) { create(:project_empty_repo) }
+
+  render_views
+
+  before(:all) do
+    clean_frontend_fixtures('issues/')
+  end
+
+  before(:each) do
+    sign_in(admin)
+  end
+
+  it 'issues/open-issue.html.raw' do |example|
+    render_issue(example.description, create(:issue, project: project))
+  end
+
+  it 'issues/closed-issue.html.raw' do |example|
+    render_issue(example.description, create(:closed_issue, project: project))
+  end
+
+  it 'issues/issue-with-task-list.html.raw' do |example|
+    issue = create(:issue, project: project)
+    issue.update(description: '- [ ] Task List Item')
+    render_issue(example.description, issue)
+  end
+
+  private
+
+  def render_issue(fixture_file_name, issue)
+    get :show,
+      namespace_id: project.namespace.to_param,
+      project_id: project.to_param,
+      id: issue.to_param
+
+    expect(response).to be_success
+    store_frontend_fixture(response, fixture_file_name)
+  end
+end
diff --git a/spec/javascripts/fixtures/issues_show.html.haml b/spec/javascripts/fixtures/issues_show.html.haml
deleted file mode 100644
index 06c2ab1e823..00000000000
--- a/spec/javascripts/fixtures/issues_show.html.haml
+++ /dev/null
@@ -1,23 +0,0 @@
-:css
-  .hidden { display: none !important; }
-
-.flash-container.flash-container-page
-  .flash-alert
-  .flash-notice
-
-.status-box.status-box-open Open
-.status-box.status-box-closed.hidden Closed
-%a.btn-close{"href" => "http://gitlab.com/issues/6/close"} Close
-%a.btn-reopen.hidden{"href" => "http://gitlab.com/issues/6/reopen"} Reopen
-
-.detail-page-description
-  .description.js-task-list-container
-    .wiki
-      %ul.task-list
-        %li.task-list-item
-          %input.task-list-item-checkbox{type: 'checkbox'}
-          Task List Item
-      %textarea.js-task-list-field
-        \- [ ] Task List Item
-
-%form.js-issuable-update{action: '/foo'}
diff --git a/spec/javascripts/issue_spec.js b/spec/javascripts/issue_spec.js
index d0c44b6346d..949114185cf 100644
--- a/spec/javascripts/issue_spec.js
+++ b/spec/javascripts/issue_spec.js
@@ -7,6 +7,10 @@
   var INVALID_URL = 'http://goesnowhere.nothing/whereami';
   var $boxClosed, $boxOpen, $btnClose, $btnReopen;
 
+  fixture.preload('issues/closed-issue.html');
+  fixture.preload('issues/issue-with-task-list.html');
+  fixture.preload('issues/open-issue.html');
+
   function expectErrorMessage() {
     var $flashMessage = $('div.flash-alert');
     expect($flashMessage).toExist();
@@ -55,33 +59,33 @@
   }
 
   describe('Issue', function() {
-    return describe('task lists', function() {
-      fixture.preload('issues_show.html');
+    describe('task lists', function() {
+      fixture.load('issues/issue-with-task-list.html');
       beforeEach(function() {
-        fixture.load('issues_show.html');
-        return this.issue = new Issue();
+        this.issue = new Issue();
       });
+
       it('modifies the Markdown field', function() {
         spyOn(jQuery, 'ajax').and.stub();
         $('input[type=checkbox]').attr('checked', true).trigger('change');
-        return expect($('.js-task-list-field').val()).toBe('- [x] Task List Item');
+        expect($('.js-task-list-field').val()).toBe('- [x] Task List Item');
       });
-      return it('submits an ajax request on tasklist:changed', function() {
+      
+      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('/foo');
-          return expect(req.data.issue.description).not.toBe(null);
+          expect(req.url).toBe('https://fixture.invalid/namespace3/project3/issues/1.json');
+          expect(req.data.issue.description).not.toBe(null);
         });
-        return $('.js-task-list-field').trigger('tasklist:changed');
+
+        $('.js-task-list-field').trigger('tasklist:changed');
       });
     });
   });
 
   describe('close issue', function() {
-    fixture.preload('issues_show.html');
-
     beforeEach(function() {
-      fixture.load('issues_show.html');
+      fixture.load('issues/open-issue.html');
       findElements();
       this.issue = new Issue();
 
@@ -134,15 +138,12 @@
   });
 
   describe('reopen issue', function() {
-    fixture.preload('issues_show.html');
-
     beforeEach(function() {
-      fixture.load('issues_show.html');
+      fixture.load('issues/closed-issue.html');
       findElements();
       this.issue = new Issue();
 
-      // TODO: fixture is an open issue, we should replace it by a closed issue
-      expectIssueState(true);
+      expectIssueState(false);
     });
 
     it('reopens an issue', function() {
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 06d52f0f735..b2ca856f89f 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -9,7 +9,7 @@ require 'shoulda/matchers'
 require 'sidekiq/testing/inline'
 require 'rspec/retry'
 
-if ENV['CI']
+if ENV['CI'] && !ENV['NO_KNAPSACK']
   require 'knapsack'
   Knapsack::Adapters::RSpecAdapter.bind
 end
diff --git a/spec/support/javascript_fixtures_helpers.rb b/spec/support/javascript_fixtures_helpers.rb
new file mode 100644
index 00000000000..adc3f48b434
--- /dev/null
+++ b/spec/support/javascript_fixtures_helpers.rb
@@ -0,0 +1,45 @@
+require 'fileutils'
+require 'gitlab/popen'
+
+module JavaScriptFixturesHelpers
+  include Gitlab::Popen
+
+  FIXTURE_PATH = 'spec/javascripts/fixtures'
+
+  # Public: Removes all fixture files from given directory
+  #
+  # directory_name - directory of the fixtures (relative to FIXTURE_PATH)
+  #
+  def clean_frontend_fixtures(directory_name)
+    directory_name = File.expand_path(directory_name, FIXTURE_PATH)
+    Dir[File.expand_path('*.html.raw', directory_name)].each do |file_name|
+      FileUtils.rm(file_name)
+    end
+  end
+
+  # Public: Store a response object as fixture file
+  #
+  # response - response object to store
+  # fixture_file_name - file name to store the fixture in (relative to FIXTURE_PATH)
+  #
+  def store_frontend_fixture(response, fixture_file_name)
+    fixture_file_name = File.expand_path(fixture_file_name, FIXTURE_PATH)
+    fixture = response.body
+
+    response_mime_type = Mime::Type.lookup(response.content_type)
+    if response_mime_type.html?
+      doc = Nokogiri::HTML::DocumentFragment.parse(fixture)
+
+      scripts = doc.css('script')
+      scripts.remove
+
+      fixture = doc.to_html
+
+      # replace relative links
+      fixture.gsub!(%r{="/}, '="https://fixture.invalid/')
+    end
+
+    FileUtils.mkdir_p(File.dirname(fixture_file_name))
+    File.write(fixture_file_name, fixture)
+  end
+end
-- 
GitLab