Commit e9bd5871 authored by Peter Leitzen's avatar Peter Leitzen

Merge branch 'jh-235732_csv_import_gmau' into 'master'

Create CSV Issue Imports table

See merge request gitlab-org/gitlab!44742
parents 98c02d63 19f862ec
# frozen_string_literal: true
class CsvIssueImport < ApplicationRecord
belongs_to :project, optional: false
belongs_to :user, optional: false
end
......@@ -10,6 +10,7 @@ module Issues
end
def execute
record_import_attempt
process_csv
email_results_to_user
......@@ -18,6 +19,10 @@ module Issues
private
def record_import_attempt
CsvIssueImport.create!(user: @user, project: @project)
end
def process_csv
csv_data = @csv_io.open(&:read).force_encoding(Encoding::UTF_8)
......
---
title: Add usage ping for unique users importing issues via CSV
merge_request: 44742
author:
type: changed
# frozen_string_literal: true
class CreateCsvIssueImports < ActiveRecord::Migration[6.0]
DOWNTIME = false
def up
create_table :csv_issue_imports do |t|
t.bigint :project_id, null: false, index: true
t.bigint :user_id, null: false, index: true
t.timestamps_with_timezone
end
end
def down
drop_table :csv_issue_imports
end
end
# frozen_string_literal: true
class AddProjectForeignKeyToCsvIssueImports < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_concurrent_foreign_key :csv_issue_imports, :projects, column: :project_id
end
def down
with_lock_retries do
remove_foreign_key :csv_issue_imports, column: :project_id
end
end
end
# frozen_string_literal: true
class AddUserForeignKeyToCsvIssueImports < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_concurrent_foreign_key :csv_issue_imports, :users, column: :user_id
end
def down
with_lock_retries do
remove_foreign_key :csv_issue_imports, column: :user_id
end
end
end
b7b15717435e06ea386c941c5a021b73f986ad3f41f2bd6f890738a79b710207
\ No newline at end of file
b8d5890fe5569127e794eea831fc18f8e5708b326e8037963fe2f6ae7f120e27
\ No newline at end of file
76e5a5bb535019da28041d1c7dddd8a18d3b04f688b38edc0c4214d3a4d6e357
\ No newline at end of file
......@@ -11270,6 +11270,23 @@ CREATE SEQUENCE conversational_development_index_metrics_id_seq
ALTER SEQUENCE conversational_development_index_metrics_id_seq OWNED BY conversational_development_index_metrics.id;
CREATE TABLE csv_issue_imports (
id bigint NOT NULL,
project_id bigint NOT NULL,
user_id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL
);
CREATE SEQUENCE csv_issue_imports_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE csv_issue_imports_id_seq OWNED BY csv_issue_imports.id;
CREATE TABLE custom_emoji (
id bigint NOT NULL,
namespace_id bigint NOT NULL,
......@@ -17523,6 +17540,8 @@ ALTER TABLE ONLY container_repositories ALTER COLUMN id SET DEFAULT nextval('con
ALTER TABLE ONLY conversational_development_index_metrics ALTER COLUMN id SET DEFAULT nextval('conversational_development_index_metrics_id_seq'::regclass);
ALTER TABLE ONLY csv_issue_imports ALTER COLUMN id SET DEFAULT nextval('csv_issue_imports_id_seq'::regclass);
ALTER TABLE ONLY custom_emoji ALTER COLUMN id SET DEFAULT nextval('custom_emoji_id_seq'::regclass);
ALTER TABLE ONLY dast_scanner_profiles ALTER COLUMN id SET DEFAULT nextval('dast_scanner_profiles_id_seq'::regclass);
......@@ -18582,6 +18601,9 @@ ALTER TABLE ONLY container_repositories
ALTER TABLE ONLY conversational_development_index_metrics
ADD CONSTRAINT conversational_development_index_metrics_pkey PRIMARY KEY (id);
ALTER TABLE ONLY csv_issue_imports
ADD CONSTRAINT csv_issue_imports_pkey PRIMARY KEY (id);
ALTER TABLE ONLY custom_emoji
ADD CONSTRAINT custom_emoji_pkey PRIMARY KEY (id);
......@@ -20222,6 +20244,10 @@ CREATE INDEX index_container_repository_on_name_trigram ON container_repositorie
CREATE INDEX index_created_at_on_codeowner_approval_merge_request_rules ON approval_merge_request_rules USING btree (created_at) WHERE ((rule_type = 2) AND (section <> 'codeowners'::text));
CREATE INDEX index_csv_issue_imports_on_project_id ON csv_issue_imports USING btree (project_id);
CREATE INDEX index_csv_issue_imports_on_user_id ON csv_issue_imports USING btree (user_id);
CREATE UNIQUE INDEX index_custom_emoji_on_namespace_id_and_name ON custom_emoji USING btree (namespace_id, name);
CREATE UNIQUE INDEX index_daily_build_group_report_results_unique_columns ON ci_daily_build_group_report_results USING btree (project_id, ref_path, date, group_name);
......@@ -22423,6 +22449,9 @@ ALTER TABLE ONLY deploy_keys_projects
ALTER TABLE ONLY issue_assignees
ADD CONSTRAINT fk_5e0c8d9154 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
ALTER TABLE ONLY csv_issue_imports
ADD CONSTRAINT fk_5e1572387c FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
ALTER TABLE ONLY project_access_tokens
ADD CONSTRAINT fk_5f7e8450e1 FOREIGN KEY (personal_access_token_id) REFERENCES personal_access_tokens(id) ON DELETE CASCADE;
......@@ -22795,6 +22824,9 @@ ALTER TABLE ONLY merge_requests
ALTER TABLE ONLY issue_links
ADD CONSTRAINT fk_e71bb44f1f FOREIGN KEY (target_id) REFERENCES issues(id) ON DELETE CASCADE;
ALTER TABLE ONLY csv_issue_imports
ADD CONSTRAINT fk_e71c0ae362 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY namespaces
ADD CONSTRAINT fk_e7a0b20a6b FOREIGN KEY (custom_project_templates_group_id) REFERENCES namespaces(id) ON DELETE SET NULL;
......
......@@ -577,7 +577,8 @@ module Gitlab
issues_imported: {
jira: distinct_count(::JiraImportState.where(time_period), :user_id),
fogbugz: projects_imported_count('fogbugz', time_period),
phabricator: projects_imported_count('phabricator', time_period)
phabricator: projects_imported_count('phabricator', time_period),
csv: distinct_count(CsvIssueImport.where(time_period), :user_id)
},
groups_imported: distinct_count(::GroupImportState.where(time_period), :user_id)
}
......
# frozen_string_literal: true
FactoryBot.define do
factory :csv_issue_import do
project
user
end
end
......@@ -207,6 +207,8 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
jira_project = create(:project, creator_id: user.id)
create(:jira_import_state, :finished, project: jira_project)
create(:csv_issue_import, user: user)
end
expect(described_class.usage_activity_by_stage_manage({})).to include(
......@@ -224,7 +226,8 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
issues_imported: {
jira: 2,
fogbugz: 2,
phabricator: 2
phabricator: 2,
csv: 2
}
}
)
......@@ -243,7 +246,8 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
issues_imported: {
jira: 1,
fogbugz: 1,
phabricator: 1
phabricator: 1,
csv: 1
}
}
)
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe CsvIssueImport, type: :model do
describe 'associations' do
it { is_expected.to belong_to(:project).required }
it { is_expected.to belong_to(:user).required }
end
end
......@@ -13,6 +13,14 @@ RSpec.describe Issues::ImportCsvService do
described_class.new(user, project, uploader).execute
end
shared_examples_for 'an issue importer' do
it 'records the import attempt' do
expect { subject }
.to change { CsvIssueImport.where(project: project, user: user).count }
.by 1
end
end
describe '#execute' do
context 'invalid file' do
let(:file) { fixture_file_upload('spec/fixtures/banana_sample.gif') }
......@@ -23,6 +31,8 @@ RSpec.describe Issues::ImportCsvService do
expect(subject[:success]).to eq(0)
expect(subject[:parse_error]).to eq(true)
end
it_behaves_like 'an issue importer'
end
context 'with a file generated by Gitlab CSV export' do
......@@ -44,6 +54,8 @@ RSpec.describe Issues::ImportCsvService do
description: 'Test Description'
)
end
it_behaves_like 'an issue importer'
end
context 'comma delimited file' do
......@@ -65,6 +77,8 @@ RSpec.describe Issues::ImportCsvService do
description: 'Description'
)
end
it_behaves_like 'an issue importer'
end
context 'tab delimited file with error row' do
......@@ -86,6 +100,8 @@ RSpec.describe Issues::ImportCsvService do
description: 'World'
)
end
it_behaves_like 'an issue importer'
end
context 'semicolon delimited file with CRLF' do
......@@ -107,6 +123,8 @@ RSpec.describe Issues::ImportCsvService do
description: 'World'
)
end
it_behaves_like 'an issue importer'
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment