From 1ad8c259d1d18e6aa709538122b8ada3ebfe63cf Mon Sep 17 00:00:00 2001 From: zmagod Date: Tue, 20 Mar 2018 14:45:57 +0100 Subject: [PATCH 01/23] add blank page for repositories [fixes SCI-2139] --- app/assets/javascripts/repositories/index.js | 74 +--------- app/assets/javascripts/repositories/show.js | 38 +++++ app/controllers/repositories_controller.rb | 19 +-- app/views/repositories/index.html.erb | 60 ++------ app/views/repositories/show.html.erb | 144 +++++++++++++++++++ config/initializers/assets.rb | 1 + config/locales/en.yml | 9 ++ config/routes.rb | 2 - 8 files changed, 213 insertions(+), 134 deletions(-) create mode 100644 app/assets/javascripts/repositories/show.js create mode 100644 app/views/repositories/show.html.erb diff --git a/app/assets/javascripts/repositories/index.js b/app/assets/javascripts/repositories/index.js index fed0920ed..f0fe68693 100644 --- a/app/assets/javascripts/repositories/index.js +++ b/app/assets/javascripts/repositories/index.js @@ -6,78 +6,8 @@ animateSpinner(); location.reload(); } - - function initImportRecordsModal() { - $('#importRecordsButton').off().on('click', function() { - $('#modal-import-records').modal('show'); - _initParseRecordsModal(); - }); - } - - function _initParseRecordsModal() { - $('#form-records-file').on('ajax:success', function(ev, data) { - $('#modal-import-records').modal('hide'); - $(data.html).appendTo('body').promise().done(function() { - $('#parse-records-modal') - .modal('show') - .on('hidden.bs.modal', function() { - animateSpinner(); - location.reload(); - }); - repositoryRecordsImporter(); - }); - }).on('ajax:error', function(ev, data) { - $(this).find('.form-group').addClass('has-error'); - $(this).find('.form-group').find('.help-block').remove(); - $(this).find('.form-group').append("" + - data.responseJSON.message + ''); - }); - } - - function loadRepositoryTab() { - var param; - $('#repository-tabs a').on("click", function(e) { - e.preventDefault(); - var pane = $(this); - $.ajax({ - url: $(this).attr("data-url"), - type: "GET", - dataType: "json", - success: function (data) { - var tabBody = $(pane.context.hash).find(".tab-content-body"); - tabBody.html(data.html); - pane.tab('show').promise().done(function(el) { - initImportRecordsModal(); - RepositoryDatatable.destroy() - RepositoryDatatable.init(el.attr('data-repo-table')); - }); - }, - error: function (error) { - // TODO - } - }); - }); - - // on page load - if( param = getParam('repository') ){ - // load selected tab - $('a[href="#custom_repo_'+param+'"]').click(); - } - else { - // load first tab content - $('#repository-tabs a:first').click(); - } - - // clean tab content - $('a[data-toggle="tab"]').on('hide.bs.tab', function (e) { - $(".tab-content-body").html(""); - }) - } - - $('.create-repository').initializeModal('#create-repo-modal'); - + $(document).ready(function() { - loadRepositoryTab(); - initImportRecordsModal(); + $('#create-new-repository').initializeModal('#create-repo-modal'); }); })(window); diff --git a/app/assets/javascripts/repositories/show.js b/app/assets/javascripts/repositories/show.js new file mode 100644 index 000000000..8bbda98e3 --- /dev/null +++ b/app/assets/javascripts/repositories/show.js @@ -0,0 +1,38 @@ +(function() { + 'use strict'; + + function initImportRecordsModal() { + $('#importRecordsButton').off().on('click', function() { + $('#modal-import-records').modal('show'); + _initParseRecordsModal(); + }); + } + + function _initParseRecordsModal() { + $('#form-records-file').on('ajax:success', function(ev, data) { + $('#modal-import-records').modal('hide'); + $(data.html).appendTo('body').promise().done(function() { + $('#parse-records-modal') + .modal('show') + .on('hidden.bs.modal', function() { + animateSpinner(); + location.reload(); + }); + repositoryRecordsImporter(); + }); + }).on('ajax:error', function(ev, data) { + $(this).find('.form-group').addClass('has-error'); + $(this).find('.form-group').find('.help-block').remove(); + $(this).find('.form-group').append("" + + data.responseJSON.message + ''); + }); + } + + function initialzerRepositoryTable() { + initImportRecordsModal(); + RepositoryDatatable.destroy(); + RepositoryDatatable.init('#' + $('.repository-table table').attr('id')); + } + + $(document).ready(initialzerRepositoryTable); +})() diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index d1d30322b..03cdf18a8 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -12,20 +12,13 @@ class RepositoriesController < ApplicationController %i(create_new_modal create copy_modal copy) def index - render('repositories/index') + unless @repositories.length.zero? && current_team + redirect_to repository_path(@repositories.first) and return + end + render 'repositories/index' end - def show_tab - respond_to do |format| - format.json do - render json: { - html: render_to_string( - partial: 'repositories/repository.html.erb', - locals: { repository: @repository } - ) - } - end - end + def show end def create_modal @@ -287,7 +280,7 @@ class RepositoriesController < ApplicationController end def load_parent_vars - @team = Team.find_by_id(params[:team_id]) + @team = current_team render_404 unless @team @repositories = @team.repositories.order(created_at: :asc) end diff --git a/app/views/repositories/index.html.erb b/app/views/repositories/index.html.erb index 2fcbbe935..1b98a2cd6 100644 --- a/app/views/repositories/index.html.erb +++ b/app/views/repositories/index.html.erb @@ -1,51 +1,19 @@ -<% provide(:head_title, t("repositories.index.head_title")) %> +<% provide(:head_title, t("libraries.index.head_title")) %> <% if current_team %> - <%= render partial: "repositories/breadcrumbs.html.erb", - locals: { teams: @teams, current_team: current_team, type: @type } %> - - - - - -
- <% @repositories.each do |repo| %> -
- -
-
-
-
- <% end %> + <% + # show only if no repositories present. If the team will have them we will + # handle this in left side navigation bar + %> +
+ <%=t 'libraries.index.no_libraries.text' %> +

<%=t 'libraries.index.no_libraries.title' %>

+
+ <%=t 'libraries.index.no_libraries.create_new_button' %>
- <% else %>
@@ -54,6 +22,4 @@
<% end %> -<%= stylesheet_link_tag 'datatables' %> -<%= javascript_include_tag 'repositories/repository_datatable' %> <%= javascript_include_tag "repositories/index", "data-turbolinks-track" => true %> diff --git a/app/views/repositories/show.html.erb b/app/views/repositories/show.html.erb new file mode 100644 index 000000000..668ffdd51 --- /dev/null +++ b/app/views/repositories/show.html.erb @@ -0,0 +1,144 @@ +<% provide(:head_title, t("libraries.show.head_title", library: @repository.name)) %> + +<%= render partial: "repositories/delete_record_modal.html.erb" %> +<%= render partial: "repositories/delete_column_modal.html.erb" %> +<%= render partial: 'repositories/export_repository_modal.html.erb', + locals: { repository: @repository } %> + +
+ +
+ + <% if can_create_repository_rows?(@repository.team) %> + + + <% end %> + + <% if can_read_team?(@repository.team) %> + + + + + <% end %> + +
+ +
+ +
+ +
+
+ + + + + + +<%= render partial: "repositories/repository_table.html.erb", + locals: { + repository: @repository, + repository_index_link: repository_table_index_path(@repository) + } +%> +<%= render partial: 'repositories/import_repository_records_modal.html.erb', + locals: { repository: @repository } %> +<%= javascript_include_tag 'repositories/edit', 'data-turbolinks-track' => true %> + + +<%= stylesheet_link_tag 'datatables' %> +<%= javascript_include_tag 'repositories/repository_datatable' %> +<%= javascript_include_tag "repositories/show", "data-turbolinks-track" => true %> diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index a4d9c0cd0..38f4189e9 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -83,6 +83,7 @@ Rails.application.config.assets.precompile += Rails.application.config.assets.precompile += %w(repositories/my_module_repository.js) Rails.application.config.assets.precompile += %w(activities/index.js) +Rails.application.config.assets.precompile += %w(repositories/show.js) # Libraries needed for Handsontable formulas Rails.application.config.assets.precompile += %w(lodash.js) diff --git a/config/locales/en.yml b/config/locales/en.yml index 2c9316b69..adccc9d6a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -984,6 +984,15 @@ en: no_records_unassigned_flash: "No items were unassigned from task" default_column: 'Name' + libraries: + index: + head_title: "Libraries" + no_libraries: + text: "You don't have any libraries." + title: "Please create your first Library" + create_new_button: "Create New Library" + show: + head_title: "Libraries | %{library}" repository_row: modal_info: head_title: "Information for record '%{repository_row}'" diff --git a/config/routes.rb b/config/routes.rb index 331b644cc..ba9becb4f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -153,8 +153,6 @@ Rails.application.routes.draw do get 'create_modal', to: 'repositories#create_modal', defaults: { format: 'json' } end - get 'show_tab', to: 'repositories#show_tab', - defaults: { format: 'json' } get 'destroy_modal', to: 'repositories#destroy_modal', defaults: { format: 'json' } get 'rename_modal', to: 'repositories#rename_modal', From 81df97f008b92237620e1ae4bba0ddfc348626a9 Mon Sep 17 00:00:00 2001 From: zmagod Date: Wed, 21 Mar 2018 09:22:55 +0100 Subject: [PATCH 02/23] add library sidebar and create new library button [fixes SCI-2121] --- .../stylesheets/themes/repositories.scss | 8 ++++++ app/assets/stylesheets/themes/scinote.scss | 2 +- app/controllers/repositories_controller.rb | 4 ++- app/views/repositories/_sidebar.html.erb | 23 +++++++++++++++ app/views/repositories/index.html.erb | 10 ++++--- app/views/repositories/show.html.erb | 28 +++++++++++++------ config/locales/en.yml | 2 ++ 7 files changed, 63 insertions(+), 14 deletions(-) create mode 100644 app/assets/stylesheets/themes/repositories.scss create mode 100644 app/views/repositories/_sidebar.html.erb diff --git a/app/assets/stylesheets/themes/repositories.scss b/app/assets/stylesheets/themes/repositories.scss new file mode 100644 index 000000000..a4244ac97 --- /dev/null +++ b/app/assets/stylesheets/themes/repositories.scss @@ -0,0 +1,8 @@ +#repository-columns-dropdown { + float: right; +} + +.new-repository-button { + float: left; + margin-right: 5px; +} diff --git a/app/assets/stylesheets/themes/scinote.scss b/app/assets/stylesheets/themes/scinote.scss index 39ae3b334..6967c9b2a 100644 --- a/app/assets/stylesheets/themes/scinote.scss +++ b/app/assets/stylesheets/themes/scinote.scss @@ -2,7 +2,7 @@ @import "mixins"; @import "main_navigation"; @import "buttons"; - +@import "repositories"; /** Layout **/ body, diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 03cdf18a8..d0351a324 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -11,6 +11,8 @@ class RepositoriesController < ApplicationController before_action :check_create_permissions, only: %i(create_new_modal create copy_modal copy) + # layout 'fluid' + def index unless @repositories.length.zero? && current_team redirect_to repository_path(@repositories.first) and return @@ -46,7 +48,7 @@ class RepositoriesController < ApplicationController if @repository.save flash[:success] = t('repositories.index.modal_create.success_flash', name: @repository.name) - render json: { url: team_repositories_path(repository: @repository) }, + render json: { url: repository_path(@repository) }, status: :ok else render json: @repository.errors, diff --git a/app/views/repositories/_sidebar.html.erb b/app/views/repositories/_sidebar.html.erb new file mode 100644 index 000000000..273fd0f17 --- /dev/null +++ b/app/views/repositories/_sidebar.html.erb @@ -0,0 +1,23 @@ + <%= content_for :sidebar do %> +
+ + +
+
    + <% repositories.each do |repository| %> + <% cache repository do %> +
  • <%= link_to repository.name, repository_path(repository) %>
  • + <% end %> + <% end %> +
+
+
+<% end %> diff --git a/app/views/repositories/index.html.erb b/app/views/repositories/index.html.erb index 1b98a2cd6..960f77ea1 100644 --- a/app/views/repositories/index.html.erb +++ b/app/views/repositories/index.html.erb @@ -1,6 +1,7 @@ <% provide(:head_title, t("libraries.index.head_title")) %> <% if current_team %> + <%= render partial: "sidebar", locals: { repositories: @repositories } %> <% # show only if no repositories present. If the team will have them we will # handle this in left side navigation bar @@ -9,10 +10,11 @@ <%=t 'libraries.index.no_libraries.text' %>

<%=t 'libraries.index.no_libraries.title' %>


- <%=t 'libraries.index.no_libraries.create_new_button' %> + <%= link_to t('libraries.index.no_libraries.create_new_button'), + create_modal_team_repositories_path(current_team), + class: "btn btn-info btn-lg", + id: "create-new-repository", + remote: true %>
<% else %> diff --git a/app/views/repositories/show.html.erb b/app/views/repositories/show.html.erb index 668ffdd51..6d1efcba6 100644 --- a/app/views/repositories/show.html.erb +++ b/app/views/repositories/show.html.erb @@ -1,10 +1,7 @@ <% provide(:head_title, t("libraries.show.head_title", library: @repository.name)) %> +<%= stylesheet_link_tag 'datatables' %> -<%= render partial: "repositories/delete_record_modal.html.erb" %> -<%= render partial: "repositories/delete_column_modal.html.erb" %> -<%= render partial: 'repositories/export_repository_modal.html.erb', - locals: { repository: @repository } %> - +<%= render partial: "sidebar", locals: { repositories: @repositories } %>
@@ -73,7 +70,18 @@
+
+
+ <% if can_create_repositories?(@repository.team) %> + <%= link_to t('libraries.index.no_libraries.create_new_button'), + create_modal_team_repositories_path(@repository.team), + class: "btn btn-default", + id: "create-new-repository", + remote: true %> + <% end %> +
+
-
+
<%=t "users.registrations.edit.avatar_btn" %>
From 659a088058437821f57b94208aab918ac33a5dd9 Mon Sep 17 00:00:00 2001 From: zmagod Date: Thu, 29 Mar 2018 15:55:26 +0200 Subject: [PATCH 08/23] refactor smart annotation parser, adds repository item to smart annotation parser [fixes SCI-2222] --- app/helpers/application_helper.rb | 63 +-------------- app/permissions/project.rb | 1 - .../smart_annotations/permision_eval.rb | 35 +++++++++ app/services/smart_annotations/preview.rb | 77 +++++++++++++++++++ app/services/smart_annotations/tag_to_html.rb | 66 ++++++++++++++++ .../smart_annotations/permission_eval_spec.rb | 47 +++++++++++ .../smart_annotations/preview_spec.rb | 63 +++++++++++++++ .../smart_annotations/tag_to_html_spec.rb | 44 +++++++++++ 8 files changed, 333 insertions(+), 63 deletions(-) create mode 100644 app/services/smart_annotations/permision_eval.rb create mode 100644 app/services/smart_annotations/preview.rb create mode 100644 app/services/smart_annotations/tag_to_html.rb create mode 100644 spec/services/smart_annotations/permission_eval_spec.rb create mode 100644 spec/services/smart_annotations/preview_spec.rb create mode 100644 spec/services/smart_annotations/tag_to_html_spec.rb diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 59dc86689..cb7c7b3ac 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -117,68 +117,7 @@ module ApplicationHelper # Check if text have smart annotations of resources # and outputs a link to resource def smart_annotation_filter_resources(text) - sa_reg = /\[\#(.*?)~(prj|exp|tsk|sam)~([0-9a-zA-Z]+)\]/ - new_text = text.gsub(sa_reg) do |el| - match = el.match(sa_reg) - case match[2] - when 'prj' - project = Project.find_by_id(match[3].base62_decode) - next unless project - if project.archived? - "" \ - "#{sanitize_input(match[2])}" \ - "#{link_to project.name, - projects_archive_path} #{I18n.t('atwho.res.archived')}" - else - "" \ - "#{sanitize_input(match[2])}" \ - "#{link_to project.name, - project_path(project)}" - end - when 'exp' - experiment = Experiment.find_by_id(match[3].base62_decode) - next unless experiment - if experiment.archived? - "" \ - "#{sanitize_input(match[2])}" \ - "#{link_to experiment.name, - experiment_archive_project_path(experiment.project)} " \ - "#{I18n.t('atwho.res.archived')}" - else - ""\ - "#{sanitize_input(match[2])}" \ - "#{link_to experiment.name, - canvas_experiment_path(experiment)}" - end - when 'tsk' - my_module = MyModule.find_by_id(match[3].base62_decode) - next unless my_module - if my_module.archived? - "" \ - "#{sanitize_input(match[2])}" \ - "#{link_to my_module.name, - module_archive_experiment_path(my_module.experiment)} " \ - "#{I18n.t('atwho.res.archived')}" - else - "" \ - "#{sanitize_input(match[2])}" \ - "#{link_to my_module.name, - protocols_my_module_path(my_module)}" - end - when 'sam' - sample = Sample.find_by_id(match[3].base62_decode) - if sample - "" \ - "#{link_to(sample.name, - sample_path(sample.id), - class: 'sample-info-link')}" - else - "" \ - "#{match[1]} #{I18n.t('atwho.res.deleted')}" - end - end - end - new_text + SmartAnnotations::TagToHtml.new(current_user, text).html end # Check if text have smart annotations of users diff --git a/app/permissions/project.rb b/app/permissions/project.rb index 3b07cf6cd..e3701db6d 100644 --- a/app/permissions/project.rb +++ b/app/permissions/project.rb @@ -16,7 +16,6 @@ Canaid::Permissions.register_for(Project) do # project: read, read activities, read comments, read users, read archive, # read notifications # reports: read - # samples: read can :read_project do |user, project| user.is_member_of_project?(project) || user.is_admin_of_team?(project.team) || diff --git a/app/services/smart_annotations/permision_eval.rb b/app/services/smart_annotations/permision_eval.rb new file mode 100644 index 000000000..87a14c443 --- /dev/null +++ b/app/services/smart_annotations/permision_eval.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module SmartAnnotations + class PermissionEval + class << self + include Canaid::Helpers::PermissionsHelper + + def check(user, type, object) + send("validate_#{type}_permissions", user, object) + end + + private + + def validate_prj_permissions(user, object) + can_read_project?(user, object) + end + + def validate_exp_permissions(user, object) + can_read_experiment?(user, object) + end + + def validate_tsk_permissions(user, object) + can_read_experiment?(user, object.experiment) + end + + def validate_sam_permissions(user, object) + can_read_team?(user, object.team) + end + + def validate_rep_item_permissions(user, object) + can_read_team?(user, object.repository.team) + end + end + end +end diff --git a/app/services/smart_annotations/preview.rb b/app/services/smart_annotations/preview.rb new file mode 100644 index 000000000..e6be1a24b --- /dev/null +++ b/app/services/smart_annotations/preview.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +module SmartAnnotations + class Preview + class << self + def html(name, type, object) + send("generate_#{type}_snippet", name, object) + end + + private + + ROUTES = Rails.application.routes.url_helpers + + def generate_prj_snippet(_, object) + if object.archived? + return "PRJ#{object.name}" \ + "#{I18n.t('atwho.res.archived')}" + end + "PRJ" \ + "#{object.name}" + end + + def generate_exp_snippet(_, object) + if object.archived? + return "EXP" \ + "#{object.name}" \ + "#{I18n.t('atwho.res.archived')}" + end + "EXP" \ + "#{object.name}" + end + + def generate_tsk_snippet(_, object) + if object.archived? + return "TSK" \ + "#{object.name}" \ + "#{I18n.t('atwho.res.archived')}" + end + "TSK" \ + "" \ + "#{object.name}" + end + + def generate_sam_snippet(name, object) + if object + return "" \ + "#{object.name}" + end + "" \ + "#{name} #{I18n.t('atwho.res.deleted')}" + end + + def generate_rep_item_snippet(name, object) + if object + repository_name = object.repository.name + return "" \ + "#{trim_repository_name(repository_name)}" \ + "" \ + "#{object.name}" + end + "REP" \ + "#{name} #{I18n.t('atwho.res.deleted')}" + end + + def trim_repository_name(name) + name.strip.slice(0..2).upcase + end + end + end +end diff --git a/app/services/smart_annotations/tag_to_html.rb b/app/services/smart_annotations/tag_to_html.rb new file mode 100644 index 000000000..522271404 --- /dev/null +++ b/app/services/smart_annotations/tag_to_html.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true +require 'smart_annotations/permision_eval' +require 'smart_annotations/preview' + +module SmartAnnotations + class TagToHtml + attr_reader :html + + def initialize(user, text) + parse(user, text) + end + + private + + REGEX = /\[\#(.*?)~(prj|exp|tsk|sam|rep_item)~([0-9a-zA-Z]+)\]/ + OBJECT_MAPPINGS = { prj: Project, + exp: Experiment, + tsk: MyModule, + sam: Sample, + rep_item: RepositoryRow }.freeze + + def parse(user, text) + @html = text.gsub(REGEX) do |el| + value = extract_values(el) + type = value[:object_type] + begin + object = fetch_object(type, value[:object_id]) + # handle samples/repository_items edge case + if type.in? %w(sam rep_item) + sample_or_repository_item(value[:name], user, type, object) + else + next unless object && SmartAnnotations::PermissionEval.check(user, + type, + object) + SmartAnnotations::Preview.html(nil, type, object) + end + rescue ActiveRecord::RecordNotFound + next + end + end + end + + def sample_or_repository_item(name, user, type, object) + if object && SmartAnnotations::PermissionEval.check(user, type, object) + return SmartAnnotations::Preview.html(nil, type, object) + end + SmartAnnotations::Preview.html(name, type, object) + end + + def extract_values(element) + match = element.match(REGEX) + { + name: match[1], + object_type: match[2], + object_id: match[3].base62_decode + } + end + + def fetch_object(type, id) + klass = OBJECT_MAPPINGS.fetch(type.to_sym) do + raise ActiveRecord::RecordNotFound.new("#{type} does not exist") + end + klass.find_by_id(id) + end + end +end diff --git a/spec/services/smart_annotations/permission_eval_spec.rb b/spec/services/smart_annotations/permission_eval_spec.rb new file mode 100644 index 000000000..0add140ba --- /dev/null +++ b/spec/services/smart_annotations/permission_eval_spec.rb @@ -0,0 +1,47 @@ +require 'rails_helper' +require 'smart_annotations/permision_eval' + +describe SmartAnnotations::PermissionEval do + let(:subject) { described_class } + let(:user) { create :user } + let(:team) { create :team } + let(:user_team) { create :user_team, user: user, team: team, role: 2 } + let(:project) { create :project, name: 'my project' } + let(:experiment) do + create :experiment, name: 'my experiment', + project: project, + created_by: user, + last_modified_by: user + end + let(:task) { create :my_module, name: 'task', experiment: experiment } + let(:repository) { create :repository, team: team, created_by: user } + let(:repository_item) { create :repository_row, repository: repository } + + describe '#validate_prj_permissions/2' do + it 'returns a boolean' do + value = subject.send(:validate_prj_permissions, user, project) + expect(value).to be_in([true, false]) + end + end + + describe '#validate_exp_permissions/2' do + it 'returns a boolean' do + value = subject.send(:validate_exp_permissions, user, experiment) + expect(value).to be_in([true, false]) + end + end + + describe '#validate_tsk_permissions/2' do + it 'returns a boolean' do + value = subject.send(:validate_tsk_permissions, user, task) + expect(value).to be_in([true, false]) + end + end + + describe '#validate_rep_item_permissions/2' do + it 'returns a boolean' do + value = subject.send(:validate_rep_item_permissions, user, repository_item) + expect(value).to be_in([true, false]) + end + end +end diff --git a/spec/services/smart_annotations/preview_spec.rb b/spec/services/smart_annotations/preview_spec.rb new file mode 100644 index 000000000..8ce623cd5 --- /dev/null +++ b/spec/services/smart_annotations/preview_spec.rb @@ -0,0 +1,63 @@ +require 'rails_helper' +require 'smart_annotations/preview' + +describe SmartAnnotations::Preview do + let(:subject) { described_class } + let(:user) { create :user } + let(:project) { create :project, name: 'my project' } + let(:experiment) do + create :experiment, name: 'my experiment', + project: project, + created_by: user, + last_modified_by: user + end + let(:task) { create :my_module, name: 'task', experiment: experiment } + + describe 'Project annotations with type prj' do + it 'returns a html snippet' do + snippet = subject.html(nil, 'prj', project) + expect(snippet).to eq( + "PRJ" \ + "my project" + ) + end + end + + context 'Experiment annotations with type exp' do + it 'returns a html snippet' do + snippet = subject.html(nil, 'exp', experiment) + expect(snippet).to eq( + "EXP" \ + "my experiment" + ) + end + end + + context 'MyModule annotations with type tsk' do + it 'returns a html snippet' do + snippet = subject.html(nil, 'tsk', task) + expect(snippet).to eq( + "TSK" \ + "task" + ) + end + end + + context 'Repository item annotations with type rep_item' do + it 'returns a html snippet' do + snippet = subject.html('my item', 'rep_item', nil) + expect(snippet).to eq( + 'REPmy item (deleted)' + ) + end + end + + describe '#trim_repository_name/1' do + it 'is returns a 3 letter upcase string' do + trimmed_repository_name = subject.__send__( + :trim_repository_name, 'banana' + ) + expect(trimmed_repository_name).to eq('BAN') + end + end +end diff --git a/spec/services/smart_annotations/tag_to_html_spec.rb b/spec/services/smart_annotations/tag_to_html_spec.rb new file mode 100644 index 000000000..a15f3f25e --- /dev/null +++ b/spec/services/smart_annotations/tag_to_html_spec.rb @@ -0,0 +1,44 @@ +require 'rails_helper' + +describe SmartAnnotations::TagToHtml do + let!(:user) { create :user } + let!(:team) { create :team } + let!(:user_team) { create :user_team, user: user, team: team, role: 2 } + let!(:project) { create :project, name: 'my project', team: team } + let!(:user_project) do + create :user_project, project: project, user: user, role: 0 + end + let(:text) do + "My annotation of [#my project~prj~#{project.id.base62_encode}]" + end + let(:subject) { described_class.new(user, text) } + describe 'Parsed text' do + it 'returns a existing string with smart annotation' do + expect(subject.html).to eq( + "My annotation of PRJ"\ + "my project" + ) + end + end + + describe '#extract_values/1' do + it 'returns a parsed hash of smart annotation' do + values = subject.send(:extract_values, '[#my project~prj~1]') + expect(values[:name]).to eq 'my project' + expect(values[:object_id]).to eq 1 + expect(values[:object_type]).to eq 'prj' + end + end + + describe '#fetch_object/2' do + it 'rises an error if type is not valid' do + expect { + subject.send(:fetch_object, 'banana', project.id) + }.to raise_error(ActiveRecord::RecordNotFound) + end + + it 'returns the required object' do + expect(subject.send(:fetch_object, 'prj', project.id)).to eq project + end + end +end From 01a548e8b3a0b9176776a1ea17ec228689dd3a97 Mon Sep 17 00:00:00 2001 From: zmagod Date: Thu, 29 Mar 2018 16:11:21 +0200 Subject: [PATCH 09/23] fix hound --- app/services/smart_annotations/preview.rb | 20 ++++++++----------- app/services/smart_annotations/tag_to_html.rb | 1 + 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/app/services/smart_annotations/preview.rb b/app/services/smart_annotations/preview.rb index e6be1a24b..108e4af52 100644 --- a/app/services/smart_annotations/preview.rb +++ b/app/services/smart_annotations/preview.rb @@ -23,11 +23,9 @@ module SmartAnnotations def generate_exp_snippet(_, object) if object.archived? - return "EXP" \ - "#{object.name}" \ - "#{I18n.t('atwho.res.archived')}" + return "EXP" \ + "#{object.name} #{I18n.t('atwho.res.archived')}" end "EXP" \ "#{object.name}" @@ -35,11 +33,10 @@ module SmartAnnotations def generate_tsk_snippet(_, object) if object.archived? - return "TSK" \ - "#{object.name}" \ - "#{I18n.t('atwho.res.archived')}" + return "TSK#{object.name} #{I18n.t('atwho.res.archived')}" end "TSK" \ "" \ @@ -62,8 +59,7 @@ module SmartAnnotations return "" \ "#{trim_repository_name(repository_name)}" \ "" \ - "#{object.name}" + "class='record-info-link'>#{object.name}" end "REP" \ "#{name} #{I18n.t('atwho.res.deleted')}" diff --git a/app/services/smart_annotations/tag_to_html.rb b/app/services/smart_annotations/tag_to_html.rb index 522271404..69616a6f8 100644 --- a/app/services/smart_annotations/tag_to_html.rb +++ b/app/services/smart_annotations/tag_to_html.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require 'smart_annotations/permision_eval' require 'smart_annotations/preview' From 802e917e69dfb22202ce507a99c94cde83e5cc01 Mon Sep 17 00:00:00 2001 From: zmagod Date: Fri, 30 Mar 2018 09:47:27 +0200 Subject: [PATCH 10/23] updated repository import modal html [fixes SCI-2235] --- app/views/repositories/_parse_records_modal.html.erb | 8 +++++++- config/locales/en.yml | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/views/repositories/_parse_records_modal.html.erb b/app/views/repositories/_parse_records_modal.html.erb index 693b12650..44c398a16 100644 --- a/app/views/repositories/_parse_records_modal.html.erb +++ b/app/views/repositories/_parse_records_modal.html.erb @@ -13,7 +13,7 @@ remote: true) do |f|%> <%= f.hidden_field :team_id, value: current_team.id %>