From 6dfdcaa814f485d3fa5b65226bccc04930949c6f Mon Sep 17 00:00:00 2001
From: Payton Burdette <pburdette@gitlab.com>
Date: Mon, 15 Apr 2024 15:11:09 +0000
Subject: [PATCH] Add new merge trains route

---
 .../javascripts/ci/merge_trains/index.js      | 32 +++++++++++++++
 .../ci/merge_trains/merge_trains_app.vue      | 14 +++++++
 .../pages/projects/merge_trains/index.js      |  3 ++
 .../projects/merge_trains_controller.rb       | 18 ++++++++
 .../projects/merge_trains/index.html.haml     |  3 ++
 .../feature_flags/wip/merge_trains_viz.yml    |  9 ++++
 ee/config/routes/project.rb                   |  2 +
 .../ci/merge_trains/merge_trains_app_spec.js  | 16 ++++++++
 .../projects/merge_trains_controller_spec.rb  | 41 +++++++++++++++++++
 9 files changed, 138 insertions(+)
 create mode 100644 ee/app/assets/javascripts/ci/merge_trains/index.js
 create mode 100644 ee/app/assets/javascripts/ci/merge_trains/merge_trains_app.vue
 create mode 100644 ee/app/assets/javascripts/pages/projects/merge_trains/index.js
 create mode 100644 ee/app/controllers/projects/merge_trains_controller.rb
 create mode 100644 ee/app/views/projects/merge_trains/index.html.haml
 create mode 100644 ee/config/feature_flags/wip/merge_trains_viz.yml
 create mode 100644 ee/spec/frontend/ci/merge_trains/merge_trains_app_spec.js
 create mode 100644 ee/spec/requests/projects/merge_trains_controller_spec.rb

diff --git a/ee/app/assets/javascripts/ci/merge_trains/index.js b/ee/app/assets/javascripts/ci/merge_trains/index.js
new file mode 100644
index 0000000000000..e1507fed9be30
--- /dev/null
+++ b/ee/app/assets/javascripts/ci/merge_trains/index.js
@@ -0,0 +1,32 @@
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import createDefaultClient from '~/lib/graphql';
+import MergeTrainsApp from './merge_trains_app.vue';
+
+Vue.use(VueApollo);
+
+const apolloProvider = new VueApollo({
+  defaultClient: createDefaultClient(),
+});
+
+export const initMergeTrainsApp = () => {
+  const el = document.querySelector('#js-merge-trains');
+
+  if (!el) {
+    return false;
+  }
+
+  const { fullPath } = el.dataset;
+
+  return new Vue({
+    el,
+    name: 'MergeTrainsRoot',
+    apolloProvider,
+    provide: {
+      fullPath,
+    },
+    render(createElement) {
+      return createElement(MergeTrainsApp);
+    },
+  });
+};
diff --git a/ee/app/assets/javascripts/ci/merge_trains/merge_trains_app.vue b/ee/app/assets/javascripts/ci/merge_trains/merge_trains_app.vue
new file mode 100644
index 0000000000000..b3f45a05c0700
--- /dev/null
+++ b/ee/app/assets/javascripts/ci/merge_trains/merge_trains_app.vue
@@ -0,0 +1,14 @@
+<script>
+export default {
+  name: 'MergeTrainsApp',
+  inject: {
+    fullPath: {
+      default: '',
+    },
+  },
+};
+</script>
+
+<template>
+  <div></div>
+</template>
diff --git a/ee/app/assets/javascripts/pages/projects/merge_trains/index.js b/ee/app/assets/javascripts/pages/projects/merge_trains/index.js
new file mode 100644
index 0000000000000..fd16debc3c811
--- /dev/null
+++ b/ee/app/assets/javascripts/pages/projects/merge_trains/index.js
@@ -0,0 +1,3 @@
+import { initMergeTrainsApp } from 'ee/ci/merge_trains/index';
+
+initMergeTrainsApp();
diff --git a/ee/app/controllers/projects/merge_trains_controller.rb b/ee/app/controllers/projects/merge_trains_controller.rb
new file mode 100644
index 0000000000000..353f3a8ab6b5b
--- /dev/null
+++ b/ee/app/controllers/projects/merge_trains_controller.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Projects
+  class MergeTrainsController < Projects::ApplicationController
+    feature_category :merge_trains
+
+    before_action :authorize_read_merge_train!
+    before_action :check_enabled!
+
+    def index; end
+
+    private
+
+    def check_enabled!
+      render_404 unless Feature.enabled?(:merge_trains_viz, project)
+    end
+  end
+end
diff --git a/ee/app/views/projects/merge_trains/index.html.haml b/ee/app/views/projects/merge_trains/index.html.haml
new file mode 100644
index 0000000000000..1d6cdc7a78eea
--- /dev/null
+++ b/ee/app/views/projects/merge_trains/index.html.haml
@@ -0,0 +1,3 @@
+- page_title _('Merge trains')
+
+#js-merge-trains{ data: { full_path: @project.full_path } }
diff --git a/ee/config/feature_flags/wip/merge_trains_viz.yml b/ee/config/feature_flags/wip/merge_trains_viz.yml
new file mode 100644
index 0000000000000..b9b9e01aad31e
--- /dev/null
+++ b/ee/config/feature_flags/wip/merge_trains_viz.yml
@@ -0,0 +1,9 @@
+---
+name: merge_trains_viz
+feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/454179
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/149025
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/455342
+milestone: '16.11'
+group: group::pipeline execution
+type: wip
+default_enabled: false
diff --git a/ee/config/routes/project.rb b/ee/config/routes/project.rb
index 91c74bba79314..10dfb68c95539 100644
--- a/ee/config/routes/project.rb
+++ b/ee/config/routes/project.rb
@@ -159,6 +159,8 @@
         end
 
         resources :compliance_frameworks, only: [:create]
+
+        resources :merge_trains, only: [:index]
       end
       # End of the /-/ scope.
 
diff --git a/ee/spec/frontend/ci/merge_trains/merge_trains_app_spec.js b/ee/spec/frontend/ci/merge_trains/merge_trains_app_spec.js
new file mode 100644
index 0000000000000..80234e97b30ea
--- /dev/null
+++ b/ee/spec/frontend/ci/merge_trains/merge_trains_app_spec.js
@@ -0,0 +1,16 @@
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import MergeTrainsApp from 'ee/ci/merge_trains/merge_trains_app.vue';
+
+describe('MergeTrainsApp', () => {
+  let wrapper;
+
+  const createComponent = () => {
+    wrapper = shallowMountExtended(MergeTrainsApp, { provide: { fullPath: 'namespace/project' } });
+  };
+
+  it('renders the merge trains app', () => {
+    createComponent();
+
+    expect(wrapper.findComponent(MergeTrainsApp).exists()).toBe(true);
+  });
+});
diff --git a/ee/spec/requests/projects/merge_trains_controller_spec.rb b/ee/spec/requests/projects/merge_trains_controller_spec.rb
new file mode 100644
index 0000000000000..ef15f3f71ea2a
--- /dev/null
+++ b/ee/spec/requests/projects/merge_trains_controller_spec.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::MergeTrainsController, type: :request, feature_category: :merge_trains do
+  let_it_be(:user) { create(:user) }
+  let_it_be(:project) { create(:project) }
+
+  describe 'GET /:namespace/:project/-/merge_trains' do
+    subject(:request) { get project_merge_trains_url(project) }
+
+    before_all do
+      project.add_maintainer(user)
+    end
+
+    before do
+      sign_in(user)
+    end
+
+    context 'when feature flag "merge_trains_viz" is enabled' do
+      it 'renders the merge trains index template' do
+        request
+
+        expect(response).to have_gitlab_http_status(:ok)
+        expect(response).to render_template('projects/merge_trains/index')
+      end
+    end
+
+    context 'when feature flag "merge_trains_viz" is disabled' do
+      before do
+        stub_feature_flags(merge_trains_viz: false)
+      end
+
+      it 'returns "not found response"' do
+        request
+
+        expect(response).to have_gitlab_http_status(:not_found)
+      end
+    end
+  end
+end
-- 
GitLab