From 1b388c798b01d950ad8692e34938a2a457c6ad0f Mon Sep 17 00:00:00 2001
From: Steve Azzopardi <steveazz@outlook.com>
Date: Tue, 4 Sep 2018 09:51:00 +0200
Subject: [PATCH] Add trigger information for job API

Create new entity called TriggerVariablesEnitity for trigger variables,
to aid reuseablity in the future.

Update JSON schema to include trigger information in the response.

Refactor rspec tests a bit to reduce duplication and for the `context`
to make sense.

closes https://gitlab.com/gitlab-org/gitlab-ce/issues/50989
---
 app/models/ci/build.rb                        |  1 +
 app/models/ci/trigger_request.rb              |  2 +
 app/serializers/build_details_entity.rb       |  6 +++
 app/serializers/trigger_variable_entity.rb    |  7 +++
 ...989-add-trigger-information-to-job-api.yml |  5 +++
 .../projects/jobs_controller_spec.rb          | 45 +++++++++++++++++++
 .../fixtures/api/schemas/job/job_details.json |  7 ++-
 spec/fixtures/api/schemas/job/trigger.json    | 28 ++++++++++++
 8 files changed, 99 insertions(+), 2 deletions(-)
 create mode 100644 app/serializers/trigger_variable_entity.rb
 create mode 100644 changelogs/unreleased/50989-add-trigger-information-to-job-api.yml
 create mode 100644 spec/fixtures/api/schemas/job/trigger.json

diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index faa160ad6ba..cc1408cb397 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -40,6 +40,7 @@ module Ci
     delegate :url, to: :runner_session, prefix: true, allow_nil: true
     delegate :terminal_specification, to: :runner_session, allow_nil: true
     delegate :gitlab_deploy_token, to: :project
+    delegate :trigger_short_token, to: :trigger_request, allow_nil: true
 
     ##
     # The "environment" field for builds is a String, and is the unexpanded name!
diff --git a/app/models/ci/trigger_request.rb b/app/models/ci/trigger_request.rb
index 913936a0bcb..0b52c690e93 100644
--- a/app/models/ci/trigger_request.rb
+++ b/app/models/ci/trigger_request.rb
@@ -8,6 +8,8 @@ module Ci
     belongs_to :pipeline, foreign_key: :commit_id
     has_many :builds
 
+    delegate :short_token, to: :trigger, prefix: true, allow_nil: true
+
     # We switched to Ci::PipelineVariable from Ci::TriggerRequest.variables.
     # Ci::TriggerRequest doesn't save variables anymore.
     validates :variables, absence: true
diff --git a/app/serializers/build_details_entity.rb b/app/serializers/build_details_entity.rb
index b107fc26f18..6f8194d9856 100644
--- a/app/serializers/build_details_entity.rb
+++ b/app/serializers/build_details_entity.rb
@@ -59,6 +59,12 @@ class BuildDetailsEntity < JobEntity
     raw_project_job_path(project, build)
   end
 
+  expose :trigger, if: -> (*) { build.trigger_request } do
+    expose :trigger_short_token, as: :short_token
+
+    expose :trigger_variables, as: :variables, using: TriggerVariableEntity
+  end
+
   private
 
   def build_failed_issue_options
diff --git a/app/serializers/trigger_variable_entity.rb b/app/serializers/trigger_variable_entity.rb
new file mode 100644
index 00000000000..56203113631
--- /dev/null
+++ b/app/serializers/trigger_variable_entity.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class TriggerVariableEntity < Grape::Entity
+  include RequestAwareEntity
+
+  expose :key, :value, :public
+end
diff --git a/changelogs/unreleased/50989-add-trigger-information-to-job-api.yml b/changelogs/unreleased/50989-add-trigger-information-to-job-api.yml
new file mode 100644
index 00000000000..5c8c78b8de8
--- /dev/null
+++ b/changelogs/unreleased/50989-add-trigger-information-to-job-api.yml
@@ -0,0 +1,5 @@
+---
+title: Add trigger information in job API
+merge_request: 21495
+author:
+type: other
diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb
index 8b6903011c3..b42f6419922 100644
--- a/spec/controllers/projects/jobs_controller_spec.rb
+++ b/spec/controllers/projects/jobs_controller_spec.rb
@@ -208,6 +208,51 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
       end
     end
 
+    context 'when requesting JSON job is triggered' do
+      let!(:merge_request) { create(:merge_request, source_project: project) }
+      let(:trigger) { create(:ci_trigger, project: project) }
+      let(:trigger_request) { create(:ci_trigger_request, pipeline: pipeline, trigger: trigger) }
+      let(:job) { create(:ci_build, pipeline: pipeline, trigger_request: trigger_request) }
+
+      before do
+        project.add_developer(user)
+        sign_in(user)
+
+        allow_any_instance_of(Ci::Build).to receive(:merge_request).and_return(merge_request)
+      end
+
+      context 'with no variables' do
+        before do
+          get_show(id: job.id, format: :json)
+        end
+
+        it 'exposes trigger information' do
+          expect(response).to have_gitlab_http_status(:ok)
+          expect(response).to match_response_schema('job/job_details')
+          expect(json_response['trigger']['short_token']).to eq 'toke'
+          expect(json_response['trigger']['variables'].length).to eq 0
+        end
+      end
+
+      context 'with variables' do
+        before do
+          create(:ci_pipeline_variable, pipeline: pipeline, key: :TRIGGER_KEY_1, value: 'TRIGGER_VALUE_1')
+
+          get_show(id: job.id, format: :json)
+        end
+
+        it 'exposes trigger information and variables' do
+          expect(response).to have_gitlab_http_status(:ok)
+          expect(response).to match_response_schema('job/job_details')
+          expect(json_response['trigger']['short_token']).to eq 'toke'
+          expect(json_response['trigger']['variables'].length).to eq 1
+          expect(json_response['trigger']['variables'].first['key']).to eq "TRIGGER_KEY_1"
+          expect(json_response['trigger']['variables'].first['value']).to eq "TRIGGER_VALUE_1"
+          expect(json_response['trigger']['variables'].first['public']).to eq false
+        end
+      end
+    end
+
     def get_show(**extra_params)
       params = {
         namespace_id: project.namespace.to_param,
diff --git a/spec/fixtures/api/schemas/job/job_details.json b/spec/fixtures/api/schemas/job/job_details.json
index b8c099250be..b82f7413b50 100644
--- a/spec/fixtures/api/schemas/job/job_details.json
+++ b/spec/fixtures/api/schemas/job/job_details.json
@@ -1,8 +1,11 @@
 {
-  "allOf": [{ "$ref": "job.json" }],
+  "allOf": [
+    { "$ref": "job.json" }
+  ],
   "description": "An extension of job.json with more detailed information",
   "properties": {
     "artifact": { "$ref": "artifact.json" },
-    "terminal_path": { "type": "string" }
+    "terminal_path": { "type": "string" },
+    "trigger": { "$ref": "trigger.json" }
   }
 }
diff --git a/spec/fixtures/api/schemas/job/trigger.json b/spec/fixtures/api/schemas/job/trigger.json
new file mode 100644
index 00000000000..1c7e9cc7693
--- /dev/null
+++ b/spec/fixtures/api/schemas/job/trigger.json
@@ -0,0 +1,28 @@
+{
+  "type": "object",
+  "required": [
+    "short_token",
+    "variables"
+  ],
+  "properties": {
+    "short_token": { "type": "string" },
+    "variables": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "key",
+          "value",
+          "public"
+        ],
+        "properties": {
+          "key": { "type": "string" },
+          "value": { "type": "string" },
+          "public": { "type": "boolean" }
+        },
+        "additionalProperties": false
+      }
+    }
+  },
+  "additionalProperties": false
+}
-- 
2.30.9