all the good changes (#1065)
This commit is contained in:
parent
3706cd83e7
commit
dde097ea75
35 changed files with 222 additions and 119 deletions
|
@ -20,9 +20,7 @@ class AccessController < ApplicationController
|
|||
|
||||
# POST maps/:id/access_request
|
||||
def access_request
|
||||
request = AccessRequest.create(user: current_user, map: @map)
|
||||
NotificationService.access_request(request)
|
||||
|
||||
AccessRequest.create(user: current_user, map: @map)
|
||||
respond_to do |format|
|
||||
format.json { head :ok }
|
||||
end
|
||||
|
@ -32,12 +30,7 @@ class AccessController < ApplicationController
|
|||
def access
|
||||
user_ids = params[:access].to_a.map(&:to_i) || []
|
||||
|
||||
@map.add_new_collaborators(user_ids).each do |user_id|
|
||||
# add_new_collaborators returns array of added users,
|
||||
# who we then send a notification to
|
||||
user = User.find(user_id)
|
||||
NotificationService.invite_to_edit(@map, current_user, user)
|
||||
end
|
||||
@map.add_new_collaborators(user_ids)
|
||||
@map.remove_old_collaborators(user_ids)
|
||||
|
||||
respond_to do |format|
|
||||
|
|
|
@ -1,31 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
module Api
|
||||
module V2
|
||||
class MappingsController < RestfulController
|
||||
class MappingsController < WithUpdatesController
|
||||
def searchable_columns
|
||||
[]
|
||||
end
|
||||
|
||||
def create
|
||||
instantiate_resource
|
||||
resource.user = current_user if current_user.present?
|
||||
resource.updated_by = current_user if current_user.present?
|
||||
authorize resource
|
||||
create_action
|
||||
respond_with_resource
|
||||
end
|
||||
|
||||
def update
|
||||
resource.updated_by = current_user if current_user.present?
|
||||
update_action
|
||||
respond_with_resource
|
||||
end
|
||||
|
||||
def destroy
|
||||
resource.updated_by = current_user if current_user.present?
|
||||
destroy_action
|
||||
head :no_content
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
module Api
|
||||
module V2
|
||||
class MapsController < RestfulController
|
||||
class MapsController < WithUpdatesController
|
||||
def searchable_columns
|
||||
[:name, :desc]
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
module Api
|
||||
module V2
|
||||
class SynapsesController < RestfulController
|
||||
class SynapsesController < WithUpdatesController
|
||||
def searchable_columns
|
||||
[:desc]
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
module Api
|
||||
module V2
|
||||
class TopicsController < RestfulController
|
||||
class TopicsController < WithUpdatesController
|
||||
def searchable_columns
|
||||
[:name, :desc, :link]
|
||||
end
|
||||
|
|
27
app/controllers/api/v2/with_updates_controller.rb
Normal file
27
app/controllers/api/v2/with_updates_controller.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
module Api
|
||||
module V2
|
||||
class WithUpdatesController < RestfulController
|
||||
def create
|
||||
instantiate_resource
|
||||
resource.user = current_user if current_user.present?
|
||||
resource.updated_by = current_user if current_user.present?
|
||||
authorize resource
|
||||
create_action
|
||||
respond_with_resource
|
||||
end
|
||||
|
||||
def update
|
||||
resource.updated_by = current_user if current_user.present?
|
||||
update_action
|
||||
respond_with_resource
|
||||
end
|
||||
|
||||
def destroy
|
||||
resource.updated_by = current_user if current_user.present?
|
||||
destroy_action
|
||||
head :no_content
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -33,6 +33,7 @@ class MappingsController < ApplicationController
|
|||
@mapping = Mapping.find(params[:id])
|
||||
authorize @mapping
|
||||
@mapping.updated_by = current_user
|
||||
@mapping.map.updated_by = current_user
|
||||
@mapping.assign_attributes(mapping_params)
|
||||
|
||||
if @mapping.save
|
||||
|
@ -47,6 +48,7 @@ class MappingsController < ApplicationController
|
|||
@mapping = Mapping.find(params[:id])
|
||||
authorize @mapping
|
||||
@mapping.updated_by = current_user
|
||||
@mapping.map.updated_by = current_user
|
||||
@mapping.destroy
|
||||
|
||||
head :no_content
|
||||
|
|
|
@ -59,6 +59,7 @@ class MapsController < ApplicationController
|
|||
def create
|
||||
@map = Map.new(create_map_params)
|
||||
@map.user = current_user
|
||||
@map.updated_by = current_user
|
||||
@map.arranged = false
|
||||
authorize @map
|
||||
|
||||
|
@ -79,8 +80,11 @@ class MapsController < ApplicationController
|
|||
|
||||
# PUT maps/:id
|
||||
def update
|
||||
@map.updated_by = current_user
|
||||
@map.assign_attributes(update_map_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @map.update_attributes(update_map_params)
|
||||
if @map.save
|
||||
format.json { head :no_content }
|
||||
else
|
||||
format.json { render json: @map.errors, status: :unprocessable_entity }
|
||||
|
@ -90,7 +94,8 @@ class MapsController < ApplicationController
|
|||
|
||||
# DELETE maps/:id
|
||||
def destroy
|
||||
@map.delete
|
||||
@map.updated_by = current_user
|
||||
@map.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
|
|
|
@ -22,6 +22,8 @@ class SynapsesController < ApplicationController
|
|||
@synapse = Synapse.new(synapse_params)
|
||||
@synapse.desc = '' if @synapse.desc.nil?
|
||||
@synapse.desc.strip! # no trailing/leading whitespace
|
||||
@synapse.user = current_user
|
||||
@synapse.updated_by = current_user
|
||||
|
||||
# we want invalid params to return :unprocessable_entity
|
||||
# so we have to authorize AFTER saving. But if authorize
|
||||
|
@ -47,9 +49,11 @@ class SynapsesController < ApplicationController
|
|||
@synapse = Synapse.find(params[:id])
|
||||
@synapse.desc = '' if @synapse.desc.nil?
|
||||
authorize @synapse
|
||||
@synapse.updated_by = current_user
|
||||
@synapse.assign_attributes(synapse_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @synapse.update_attributes(synapse_params)
|
||||
if @synapse.save
|
||||
format.json { head :no_content }
|
||||
else
|
||||
format.json { render json: @synapse.errors, status: :unprocessable_entity }
|
||||
|
@ -61,6 +65,7 @@ class SynapsesController < ApplicationController
|
|||
def destroy
|
||||
@synapse = Synapse.find(params[:id])
|
||||
authorize @synapse
|
||||
@synapse.updated_by = current_user
|
||||
@synapse.destroy
|
||||
|
||||
respond_to do |format|
|
||||
|
@ -72,7 +77,7 @@ class SynapsesController < ApplicationController
|
|||
|
||||
def synapse_params
|
||||
params.require(:synapse).permit(
|
||||
:id, :desc, :category, :weight, :permission, :topic1_id, :topic2_id, :user_id
|
||||
:id, :desc, :category, :weight, :permission, :topic1_id, :topic2_id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -134,6 +134,8 @@ class TopicsController < ApplicationController
|
|||
def create
|
||||
@topic = Topic.new(topic_params)
|
||||
authorize @topic
|
||||
@topic.user = current_user
|
||||
@topic.updated_by = current_user
|
||||
|
||||
respond_to do |format|
|
||||
if @topic.save
|
||||
|
@ -149,9 +151,11 @@ class TopicsController < ApplicationController
|
|||
def update
|
||||
@topic = Topic.find(params[:id])
|
||||
authorize @topic
|
||||
@topic.updated_by = current_user
|
||||
@topic.assign_attributes(topic_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @topic.update_attributes(topic_params)
|
||||
if @topic.save
|
||||
format.json { head :no_content }
|
||||
else
|
||||
format.json { render json: @topic.errors, status: :unprocessable_entity }
|
||||
|
@ -163,7 +167,7 @@ class TopicsController < ApplicationController
|
|||
def destroy
|
||||
@topic = Topic.find(params[:id])
|
||||
authorize @topic
|
||||
|
||||
@topic.updated_by = current_user
|
||||
@topic.destroy
|
||||
respond_to do |format|
|
||||
format.json { head :no_content }
|
||||
|
@ -173,6 +177,6 @@ class TopicsController < ApplicationController
|
|||
private
|
||||
|
||||
def topic_params
|
||||
params.require(:topic).permit(:id, :name, :desc, :link, :permission, :user_id, :metacode_id, :defer_to_map_id)
|
||||
params.require(:topic).permit(:id, :name, :desc, :link, :permission, :metacode_id, :defer_to_map_id)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,15 +9,16 @@ class ApplicationMailer < ActionMailer::Base
|
|||
|
||||
class << self
|
||||
def mail_for_notification(notification)
|
||||
if notification.notification_code == MAILBOXER_CODE_ACCESS_REQUEST
|
||||
request = notification.notified_object
|
||||
MapMailer.access_request_email(request)
|
||||
elsif notification.notification_code == MAILBOXER_CODE_ACCESS_APPROVED
|
||||
request = notification.notified_object
|
||||
MapMailer.access_approved_email(request)
|
||||
elsif notification.notification_code == MAILBOXER_CODE_INVITE_TO_EDIT
|
||||
user_map = notification.notified_object
|
||||
MapMailer.invite_to_edit_email(user_map.map, user_map.map.user, user_map.user)
|
||||
case notification.notification_code
|
||||
when MAILBOXER_CODE_ACCESS_REQUEST
|
||||
request = notification.notified_object
|
||||
MapMailer.access_request(request)
|
||||
when MAILBOXER_CODE_ACCESS_APPROVED
|
||||
request = notification.notified_object
|
||||
MapMailer.access_approved(request)
|
||||
when MAILBOXER_CODE_INVITE_TO_EDIT
|
||||
user_map = notification.notified_object
|
||||
MapMailer.invite_to_edit(user_map)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,21 +2,21 @@
|
|||
class MapMailer < ApplicationMailer
|
||||
default from: 'team@metamaps.cc'
|
||||
|
||||
def access_request_email(request)
|
||||
def access_request(request)
|
||||
@request = request
|
||||
@map = request.map
|
||||
mail(to: @map.user.email, subject: request.requested_text)
|
||||
end
|
||||
|
||||
def access_approved_email(request)
|
||||
def access_approved(request)
|
||||
@request = request
|
||||
@map = request.map
|
||||
mail(to: request.user, subject: request.approved_text)
|
||||
end
|
||||
|
||||
def invite_to_edit_email(map, inviter, invitee)
|
||||
@inviter = inviter
|
||||
@map = map
|
||||
mail(to: invitee.email, subject: map.invited_text)
|
||||
def invite_to_edit(user_map)
|
||||
@inviter = user_map.map.user
|
||||
@map = user_map.map
|
||||
mail(to: user_map.user.email, subject: map.invited_text)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
class AccessRequest < ApplicationRecord
|
||||
belongs_to :user
|
||||
belongs_to :map
|
||||
has_one :user_map
|
||||
|
||||
after_create :after_created_async
|
||||
|
||||
def approve
|
||||
self.approved = true
|
||||
|
@ -12,8 +15,7 @@ class AccessRequest < ApplicationRecord
|
|||
Mailboxer::Receipt.where(notification: notification).update_all(is_read: true)
|
||||
end
|
||||
|
||||
UserMap.create(user: user, map: map)
|
||||
NotificationService.access_approved(self)
|
||||
UserMap.create(user: user, map: map, access_request: self)
|
||||
end
|
||||
|
||||
def deny
|
||||
|
@ -33,4 +35,11 @@ class AccessRequest < ApplicationRecord
|
|||
def approved_text
|
||||
map.name + ' - access approved'
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def after_created_async
|
||||
NotificationService.access_request(self)
|
||||
end
|
||||
handle_asynchronously :after_created_async
|
||||
end
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
class Map < ApplicationRecord
|
||||
ATTRS_TO_WATCH = %w(name desc permission).freeze
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :source, class_name: :Map
|
||||
belongs_to :updated_by, class_name: 'User'
|
||||
|
||||
has_many :topicmappings, -> { Mapping.topicmapping },
|
||||
class_name: :Mapping, dependent: :destroy
|
||||
|
@ -10,7 +13,7 @@ class Map < ApplicationRecord
|
|||
has_many :topics, through: :topicmappings, source: :mappable, source_type: 'Topic'
|
||||
has_many :synapses, through: :synapsemappings, source: :mappable, source_type: 'Synapse'
|
||||
has_many :messages, as: :resource, dependent: :destroy
|
||||
has_many :stars
|
||||
has_many :stars, dependent: :destroy
|
||||
|
||||
has_many :access_requests, dependent: :destroy
|
||||
has_many :user_maps, dependent: :destroy
|
||||
|
@ -126,13 +129,7 @@ class Map < ApplicationRecord
|
|||
end
|
||||
removed.compact
|
||||
end
|
||||
|
||||
def after_updated
|
||||
attrs = %w(name desc permission)
|
||||
return unless attrs.any? { |k| changed_attributes.key?(k) }
|
||||
ActionCable.server.broadcast 'map_' + id.to_s, type: 'mapUpdated'
|
||||
end
|
||||
|
||||
|
||||
def update_deferring_topics_and_synapses
|
||||
Topic.where(defer_to_map_id: id).update(permission: permission)
|
||||
Synapse.where(defer_to_map_id: id).update(permission: permission)
|
||||
|
@ -141,4 +138,12 @@ class Map < ApplicationRecord
|
|||
def invited_text
|
||||
name + ' - invited to edit'
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def after_updated
|
||||
return unless ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) }
|
||||
ActionCable.server.broadcast 'map_' + id.to_s, type: 'mapUpdated'
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
class Synapse < ApplicationRecord
|
||||
ATTRS_TO_WATCH = %w(desc category permission defer_to_map_id).freeze
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :defer_to_map, class_name: 'Map', foreign_key: 'defer_to_map_id'
|
||||
belongs_to :updated_by, class_name: 'User'
|
||||
|
||||
belongs_to :topic1, class_name: 'Topic', foreign_key: 'topic1_id'
|
||||
belongs_to :topic2, class_name: 'Topic', foreign_key: 'topic2_id'
|
||||
|
@ -71,13 +74,12 @@ class Synapse < ApplicationRecord
|
|||
end
|
||||
|
||||
def after_updated
|
||||
attrs = %w(desc category permission defer_to_map_id)
|
||||
if attrs.any? { |k| changed_attributes.key?(k) }
|
||||
new = attributes.select { |k| attrs.include?(k) }
|
||||
old = changed_attributes.select { |k| attrs.include?(k) }
|
||||
if ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) }
|
||||
new = attributes.select { |k| ATTRS_TO_WATCH.include?(k) }
|
||||
old = changed_attributes.select { |k| ATTRS_TO_WATCH.include?(k) }
|
||||
meta = new.merge(old) # we are prioritizing the old values, keeping them
|
||||
meta['changed'] = changed_attributes.keys.select { |k| attrs.include?(k) }
|
||||
Events::SynapseUpdated.publish!(self, user, meta)
|
||||
meta['changed'] = changed_attributes.keys.select { |k| ATTRS_TO_WATCH.include?(k) }
|
||||
Events::SynapseUpdated.publish!(self, updated_by, meta)
|
||||
maps.each do |map|
|
||||
ActionCable.server.broadcast 'map_' + map.id.to_s, type: 'synapseUpdated', id: id
|
||||
end
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
class Topic < ApplicationRecord
|
||||
ATTRS_TO_WATCH = %w(name desc link metacode_id permission defer_to_map_id).freeze
|
||||
include TopicsHelper
|
||||
include Attachable
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :defer_to_map, class_name: 'Map', foreign_key: 'defer_to_map_id'
|
||||
belongs_to :updated_by, class_name: 'User'
|
||||
|
||||
has_many :synapses1, class_name: 'Synapse', foreign_key: 'topic1_id', dependent: :destroy
|
||||
has_many :synapses2, class_name: 'Synapse', foreign_key: 'topic2_id', dependent: :destroy
|
||||
|
@ -149,13 +151,12 @@ class Topic < ApplicationRecord
|
|||
end
|
||||
|
||||
def after_updated
|
||||
attrs = %w(name desc link metacode_id permission defer_to_map_id)
|
||||
if attrs.any? { |k| changed_attributes.key?(k) }
|
||||
new = attributes.select { |k| attrs.include?(k) }
|
||||
old = changed_attributes.select { |k| attrs.include?(k) }
|
||||
if ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) }
|
||||
new = attributes.select { |k| ATTRS_TO_WATCH.include?(k) }
|
||||
old = changed_attributes.select { |k| ATTRS_TO_WATCH.include?(k) }
|
||||
meta = new.merge(old) # we are prioritizing the old values, keeping them
|
||||
meta['changed'] = changed_attributes.keys.select { |k| attrs.include?(k) }
|
||||
Events::TopicUpdated.publish!(self, user, meta)
|
||||
meta['changed'] = changed_attributes.keys.select { |k| ATTRS_TO_WATCH.include?(k) }
|
||||
Events::TopicUpdated.publish!(self, updated_by, meta)
|
||||
maps.each do |map|
|
||||
ActionCable.server.broadcast 'map_' + map.id.to_s, type: 'topicUpdated', id: id
|
||||
end
|
||||
|
|
|
@ -2,10 +2,24 @@
|
|||
class UserMap < ApplicationRecord
|
||||
belongs_to :map
|
||||
belongs_to :user
|
||||
belongs_to :access_request
|
||||
|
||||
after_create :after_created_async
|
||||
|
||||
def mark_invite_notifications_as_read
|
||||
Mailboxer::Notification.where(notified_object: self).find_each do |notification|
|
||||
Mailboxer::Receipt.where(notification: notification).update_all(is_read: true)
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def after_created_async
|
||||
if access_request
|
||||
NotificationService.access_approved(self.access_request)
|
||||
else
|
||||
NotificationService.invite_to_edit(self)
|
||||
end
|
||||
end
|
||||
handle_asynchronously :after_created_async
|
||||
end
|
||||
|
|
|
@ -10,23 +10,46 @@ class NotificationService
|
|||
)
|
||||
end
|
||||
|
||||
def self.get_template_for_event_type(event_type)
|
||||
'map_mailer/' + event_type
|
||||
end
|
||||
|
||||
def self.get_mailboxer_code_for_event_type(event_type)
|
||||
case event_type
|
||||
when 'access_approved'
|
||||
MAILBOXER_CODE_ACCESS_APPROVED
|
||||
when 'access_request'
|
||||
MAILBOXER_CODE_ACCESS_REQUEST
|
||||
when 'invite_to_edit'
|
||||
MAILBOXER_CODE_INVITE_TO_EDIT
|
||||
end
|
||||
end
|
||||
|
||||
def self.access_request(request)
|
||||
body = renderer.render(template: 'map_mailer/access_request_email', locals: { map: request.map, request: request }, layout: false)
|
||||
request.map.user.notify(request.requested_text, body, request, false, MAILBOXER_CODE_ACCESS_REQUEST, true, request.user)
|
||||
event_type = 'access_request'
|
||||
template = get_template_for_event_type(event_type)
|
||||
mailboxer_code = get_mailboxer_code_for_event_type(event_type)
|
||||
body = renderer.render(template: template, locals: { map: request.map, request: request }, layout: false)
|
||||
request.map.user.notify(request.requested_text, body, request, false, mailboxer_code, true, request.user)
|
||||
end
|
||||
|
||||
def self.access_approved(request)
|
||||
body = renderer.render(template: 'map_mailer/access_approved_email', locals: { map: request.map }, layout: false)
|
||||
request.user.notify(request.approved_text, body, request, false, MAILBOXER_CODE_ACCESS_APPROVED, true, request.map.user)
|
||||
event_type = 'access_approved'
|
||||
template = get_template_for_event_type(event_type)
|
||||
mailboxer_code = get_mailboxer_code_for_event_type(event_type)
|
||||
body = renderer.render(template: template, locals: { map: request.map }, layout: false)
|
||||
request.user.notify(request.approved_text, body, request, false, mailboxer_code, true, request.map.user)
|
||||
end
|
||||
|
||||
def self.invite_to_edit(map, inviter, invited)
|
||||
user_map = UserMap.find_by(user: invited, map: map)
|
||||
body = renderer.render(template: 'map_mailer/invite_to_edit_email', locals: { map: map, inviter: inviter }, layout: false)
|
||||
invited.notify(map.invited_text, body, user_map, false, MAILBOXER_CODE_INVITE_TO_EDIT, true, inviter)
|
||||
def self.invite_to_edit(user_map)
|
||||
event_type = 'invite_to_edit'
|
||||
template = get_template_for_event_type(event_type)
|
||||
mailboxer_code = get_mailboxer_code_for_event_type(event_type)
|
||||
body = renderer.render(template: template, locals: { map: user_map.map, inviter: user_map.map.user }, layout: false)
|
||||
user_map.user.notify(map.invited_text, body, user_map, false, mailboxer_code, true, user_map.map.user)
|
||||
end
|
||||
|
||||
# note: this is a global function, probaobly called from the rails console with some html body
|
||||
# note: this is a global function, probably called from the rails console with some html body
|
||||
def self.message_from_devs(subject, body, opts = {})
|
||||
users = opts[:users] || User.all
|
||||
obj = opts[:obj] || nil
|
||||
|
@ -38,17 +61,18 @@ class NotificationService
|
|||
end
|
||||
|
||||
def self.text_for_notification(notification)
|
||||
if notification.notification_code == MAILBOXER_CODE_ACCESS_REQUEST
|
||||
map = notification.notified_object.map
|
||||
'wants permission to map with you on <span class="in-bold">' + map.name + '</span> <div class="action">Offer a response</div>'
|
||||
elsif notification.notification_code == MAILBOXER_CODE_ACCESS_APPROVED
|
||||
map = notification.notified_object.map
|
||||
'granted your request to edit map <span class="in-bold">' + map.name + '</span>'
|
||||
elsif notification.notification_code == MAILBOXER_CODE_INVITE_TO_EDIT
|
||||
map = notification.notified_object.map
|
||||
'gave you edit access to map <span class="in-bold">' + map.name + '</span>'
|
||||
elsif notification.notification_code == MAILBOXER_CODE_MESSAGE_FROM_DEVS
|
||||
notification.subject
|
||||
case notification.notification_code
|
||||
when MAILBOXER_CODE_ACCESS_APPROVED
|
||||
map = notification.notified_object.map
|
||||
'granted your request to edit map <span class="in-bold">' + map.name + '</span>'
|
||||
when MAILBOXER_CODE_ACCESS_REQUEST
|
||||
map = notification.notified_object.map
|
||||
'wants permission to map with you on <span class="in-bold">' + map.name + '</span> <div class="action">Offer a response</div>'
|
||||
when MAILBOXER_CODE_INVITE_TO_EDIT
|
||||
map = notification.notified_object.map
|
||||
'gave you edit access to map <span class="in-bold">' + map.name + '</span>'
|
||||
when MAILBOXER_CODE_MESSAGE_FROM_DEVS
|
||||
notification.subject
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class AddAccessRequestToUserMap < ActiveRecord::Migration[5.0]
|
||||
def change
|
||||
add_reference :user_maps, :access_request
|
||||
end
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
class AddUpdatedByToTopicsSynapsesAndMaps < ActiveRecord::Migration[5.0]
|
||||
def change
|
||||
add_reference :topics, :updated_by, foreign_key: {to_table: :users}
|
||||
add_reference :synapses, :updated_by, foreign_key: {to_table: :users}
|
||||
add_reference :maps, :updated_by, foreign_key: {to_table: :users}
|
||||
end
|
||||
end
|
17
db/schema.rb
17
db/schema.rb
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20170122201451) do
|
||||
ActiveRecord::Schema.define(version: 20170208161305) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -164,7 +164,9 @@ ActiveRecord::Schema.define(version: 20170122201451) do
|
|||
t.integer "screenshot_file_size"
|
||||
t.datetime "screenshot_updated_at"
|
||||
t.integer "source_id"
|
||||
t.integer "updated_by_id"
|
||||
t.index ["source_id"], name: "index_maps_on_source_id", using: :btree
|
||||
t.index ["updated_by_id"], name: "index_maps_on_updated_by_id", using: :btree
|
||||
t.index ["user_id"], name: "index_maps_on_user_id", using: :btree
|
||||
end
|
||||
|
||||
|
@ -259,10 +261,12 @@ ActiveRecord::Schema.define(version: 20170122201451) do
|
|||
t.text "permission"
|
||||
t.text "weight"
|
||||
t.integer "defer_to_map_id"
|
||||
t.index ["topic1_id", "topic1_id"], name: "index_synapses_on_node1_id_and_node1_id", using: :btree
|
||||
t.integer "updated_by_id"
|
||||
t.index ["topic1_id"], name: "index_synapses_on_node1_id_and_node1_id", using: :btree
|
||||
t.index ["topic1_id"], name: "index_synapses_on_topic1_id", using: :btree
|
||||
t.index ["topic2_id", "topic2_id"], name: "index_synapses_on_node2_id_and_node2_id", using: :btree
|
||||
t.index ["topic2_id"], name: "index_synapses_on_node2_id_and_node2_id", using: :btree
|
||||
t.index ["topic2_id"], name: "index_synapses_on_topic2_id", using: :btree
|
||||
t.index ["updated_by_id"], name: "index_synapses_on_updated_by_id", using: :btree
|
||||
t.index ["user_id"], name: "index_synapses_on_user_id", using: :btree
|
||||
end
|
||||
|
||||
|
@ -285,7 +289,9 @@ ActiveRecord::Schema.define(version: 20170122201451) do
|
|||
t.datetime "updated_at", null: false
|
||||
t.text "permission"
|
||||
t.integer "defer_to_map_id"
|
||||
t.integer "updated_by_id"
|
||||
t.index ["metacode_id"], name: "index_topics_on_metacode_id", using: :btree
|
||||
t.index ["updated_by_id"], name: "index_topics_on_updated_by_id", using: :btree
|
||||
t.index ["user_id"], name: "index_topics_on_user_id", using: :btree
|
||||
end
|
||||
|
||||
|
@ -294,6 +300,8 @@ ActiveRecord::Schema.define(version: 20170122201451) do
|
|||
t.integer "map_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.integer "access_request_id"
|
||||
t.index ["access_request_id"], name: "index_user_maps_on_access_request_id", using: :btree
|
||||
t.index ["map_id"], name: "index_user_maps_on_map_id", using: :btree
|
||||
t.index ["user_id"], name: "index_user_maps_on_user_id", using: :btree
|
||||
end
|
||||
|
@ -347,5 +355,8 @@ ActiveRecord::Schema.define(version: 20170122201451) do
|
|||
add_foreign_key "mailboxer_receipts", "mailboxer_notifications", column: "notification_id", name: "receipts_on_notification_id"
|
||||
add_foreign_key "mappings", "users", column: "updated_by_id"
|
||||
add_foreign_key "maps", "maps", column: "source_id"
|
||||
add_foreign_key "maps", "users", column: "updated_by_id"
|
||||
add_foreign_key "synapses", "users", column: "updated_by_id"
|
||||
add_foreign_key "tokens", "users"
|
||||
add_foreign_key "topics", "users", column: "updated_by_id"
|
||||
end
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe TopicsController, type: :controller do
|
||||
let(:topic) { create(:topic) }
|
||||
let(:user) { create(:user) }
|
||||
let(:topic) { create(:topic, user: user) }
|
||||
let(:valid_attributes) { topic.attributes.except('id') }
|
||||
let(:invalid_attributes) { { permission: :invalid_lol } }
|
||||
before :each do
|
||||
sign_in create(:user)
|
||||
sign_in :user
|
||||
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
|
|
|
@ -7,5 +7,6 @@ FactoryGirl.define do
|
|||
source_id nil
|
||||
desc ''
|
||||
user
|
||||
association :updated_by, factory: :user
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,6 +7,7 @@ FactoryGirl.define do
|
|||
association :topic1, factory: :topic
|
||||
association :topic2, factory: :topic
|
||||
user
|
||||
association :updated_by, factory: :user
|
||||
weight 1 # TODO: drop this column
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
FactoryGirl.define do
|
||||
factory :topic do
|
||||
user
|
||||
association :updated_by, factory: :user
|
||||
metacode
|
||||
permission :commons
|
||||
sequence(:name) { |n| "Cool Topic ##{n}" }
|
||||
|
|
7
spec/factories/user_maps.rb
Normal file
7
spec/factories/user_maps.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
FactoryGirl.define do
|
||||
factory :user_map do
|
||||
map
|
||||
user
|
||||
end
|
||||
end
|
|
@ -2,10 +2,10 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe MapMailer, type: :mailer do
|
||||
describe 'access_request_email' do
|
||||
describe 'access_request' do
|
||||
let(:map) { create(:map) }
|
||||
let(:request) { create(:access_request, map: map) }
|
||||
let(:mail) { described_class.access_request_email(request) }
|
||||
let(:mail) { described_class.access_request(request) }
|
||||
|
||||
it { expect(mail.from).to eq ['team@metamaps.cc'] }
|
||||
it { expect(mail.to).to eq [map.user.email] }
|
||||
|
@ -16,17 +16,17 @@ RSpec.describe MapMailer, type: :mailer do
|
|||
it { expect(mail.body.encoded).to match 'Decline' }
|
||||
end
|
||||
|
||||
describe 'invite_to_edit_email' do
|
||||
let(:map) { create(:map) }
|
||||
describe 'invite_to_edit' do
|
||||
let(:inviter) { create(:user) }
|
||||
let(:invitee) { create(:user) }
|
||||
let(:mail) { described_class.invite_to_edit_email(map, inviter, invitee) }
|
||||
let(:map) { create(:map, user: inviter) }
|
||||
let(:invited) { create(:user) }
|
||||
let(:user_map) { create(:user_map, map: map, user: invited) }
|
||||
let(:mail) { described_class.invite_to_edit(user_map) }
|
||||
|
||||
it { expect(mail.from).to eq ['team@metamaps.cc'] }
|
||||
it { expect(mail.to).to eq [invitee.email] }
|
||||
it { expect(mail.to).to eq [invited.email] }
|
||||
it { expect(mail.subject).to match map.name }
|
||||
it { expect(mail.body.encoded).to match inviter.name }
|
||||
it { expect(mail.body.encoded).to match map.name }
|
||||
it { expect(mail.body.encoded).to match map_url(map) }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
# Preview all emails at http://localhost:3000/rails/mailers/map_mailer
|
||||
class MapMailerPreview < ActionMailer::Preview
|
||||
def invite_to_edit_email
|
||||
MapMailer.invite_to_edit_email(Map.first, User.first, User.second)
|
||||
def invite_to_edit
|
||||
user_map = UserMap.first
|
||||
MapMailer.invite_to_edit(user_map)
|
||||
end
|
||||
|
||||
def access_request_email
|
||||
request = AccessRequest.first
|
||||
MapMailer.access_request_email(request)
|
||||
MapMailer.access_request(request)
|
||||
end
|
||||
|
||||
def access_approved_email
|
||||
request = AccessRequest.first
|
||||
MapMailer.access_approved_email(request)
|
||||
MapMailer.access_approved(request)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,8 +11,6 @@ RSpec.describe AccessRequest, type: :model do
|
|||
|
||||
it { expect(access_request.approved).to be true }
|
||||
it { expect(access_request.answered).to be true }
|
||||
it { expect(UserMap.count).to eq 1 }
|
||||
it { expect(Mailboxer::Notification.count).to eq 1 }
|
||||
end
|
||||
|
||||
describe 'deny' do
|
||||
|
@ -22,7 +20,5 @@ RSpec.describe AccessRequest, type: :model do
|
|||
|
||||
it { expect(access_request.approved).to be false }
|
||||
it { expect(access_request.answered).to be true }
|
||||
it { expect(UserMap.count).to eq 0 }
|
||||
it { expect(Mailboxer::Notification.count).to eq 0 }
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue