Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spike of community resource browsing #980

Merged
merged 16 commits into from
Dec 10, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions app/blueprints/contribution_blueprint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
class ContributionBlueprint < Blueprinter::Base
identifier :id
association :categories_for_tags, name: :category_tags, blueprint: DefaultBlueprint
association :service_area, blueprint: ServiceAreaBlueprint, view: :with_location
association :service_area, blueprint: ServiceAreaBlueprint, view: :with_location do |contribution|
contribution.service_areas.first
h-m-m marked this conversation as resolved.
Show resolved Hide resolved
end

association :contact_types, blueprint: DefaultBlueprint do |contribution, _options|
[contribution.person.preferred_contact_method]
[contribution.preferred_contact_method]
end
association :urgency, blueprint: DefaultBlueprint do |contribution, _options|
UrgencyLevel.find(contribution.urgency_level_id)
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/contributions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ def index
@filter_groupings = BrowseFilter.filter_groupings_json
# The BrowserFilter takes the result of the parameters from the filter checkboxes and returns a list of contributions
filter = BrowseFilter.new(allowed_params)
spike_array = filter.contributions #+ CommunityResource.published
@contributions = ContributionBlueprint.render(
filter.contributions,
spike_array,
show_view_path: true,
current_user: context.user
)
Expand Down
4 changes: 4 additions & 0 deletions app/filters/contact_method_filter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ def self.filter_grouping

def filter(scope)
return super unless parameters

# We may want to add contact method logic for community resources. For now, this effectively allows all
return super unless scope.respond_to? :person_id

scope.joins(:person).where(people: {preferred_contact_method: parameters.keys})
end
end
5 changes: 3 additions & 2 deletions app/filters/contribution_type_filter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ class ContributionTypeFilter < BaseFilter
def self.filter_grouping
{name: 'Contribution Types', filter_options: [
{id: 'ContributionType[Ask]', name: 'Ask'},
{id: 'ContributionType[Offer]', name: 'Offer'}
{id: 'ContributionType[Offer]', name: 'Offer'},
{id: 'ContributionType[CommunityResource]', name: 'Community Resource'}
]}
end
ALL_ALLOWED_TYPES = ['Ask', 'Offer'].freeze
ALL_ALLOWED_TYPES = %w[Ask Offer CommunityResource].freeze

def filter(scope)
raise NotImplementedError.new(
Expand Down
2 changes: 1 addition & 1 deletion app/filters/service_area_filter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ def self.filter_grouping

def filter(scope)
return super unless parameters
scope.where(service_area_id: parameters.keys)
scope.in_service_areas(parameters.keys)
end
end
2 changes: 1 addition & 1 deletion app/javascript/pages/browse/TileListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<div v-if="service_area" class="has-text-grey-lighter">
{{ service_area.name }}
</div>
<div v-if="person.name" class="contributor-name">
<div v-if="person && person.name" class="contributor-name">
{{ `From: ${person.name}` }}
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions app/models/ask.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class Ask < Listing
scope :matched, -> { includes(:matches_as_receiver).references(:matches_as_receiver).where.not(matches: {provider_id: nil}) }
scope :unmatched, -> { includes(:matches_as_receiver).references(:matches_as_receiver).where(matches: {provider_id: nil}) }
scope :matchable, -> { where(id: unmatched.pluck(:id) + inexhaustible.pluck(:id)) }
scope :in_service_areas, ->(ids) { where(service_area_id: ids) }
end

# == Schema Information
Expand Down
28 changes: 28 additions & 0 deletions app/models/community_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class CommunityResource < ApplicationRecord

scope :approved, -> { where(is_approved: true) }
scope :pending_review, -> { where(is_approved: false) }
# TODO: add tests for this?
scope :in_service_areas, ->(ids) { joins(:service_areas).where(service_areas: {id: ids}).distinct }

def self.published
before_now = DateTime.new..Time.current
Expand All @@ -31,20 +33,46 @@ def self.published
)
end

def title; description; end
def self.matchable; published; end

def published?
now = Time.current
is_approved &&
(publish_from.present? ? publish_from <= now : true) &&
(publish_until.nil? || now < publish_until)
end

def categories_for_tags
Category.where(name: tag_list)
h-m-m marked this conversation as resolved.
Show resolved Hide resolved
end

def all_tags_unique
all_tags_list.flatten.map(&:downcase).uniq
end

def all_tags_to_s
all_tags_unique.join(', ')
end

def preferred_contact_method
# TODO: This is a hack that makes the tests pass for now
ContactMethod.method_name('call').last
end

def type
"Community Resource"
end

def inexhaustible
true
end

def urgency_level_id
UrgencyLevel::TYPES.last.id
end
Comment on lines +70 to +80
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@exbinary mentioned that these don't feel like actual attributes, behaviors, or properties of a community resource, and so they might be better off in an abstraction or interface class that turns community resources into something blueprint-able


def person; end
end

# == Schema Information
Expand Down
8 changes: 8 additions & 0 deletions app/models/listing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,17 @@ def categories_for_tags
Category.where(name: tag_list)
end

def service_areas
[service_area]
end

def has_email?
person.email.present?
end

def preferred_contact_method
person.preferred_contact_method
end
end

# == Schema Information
Expand Down
1 change: 1 addition & 0 deletions app/models/offer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class Offer < Listing
scope :matched, -> { includes(:matches_as_provider).references(:matches_as_provider).where.not(matches: {receiver_id: nil}) }
scope :unmatched, -> { includes(:matches_as_provider).references(:matches_as_provider).where(matches: {receiver_id: nil}) }
scope :matchable, -> { where(id: unmatched.pluck(:id) + inexhaustible.pluck(:id)) }
scope :in_service_areas, ->(ids) { where(service_area_id: ids) }
h-m-m marked this conversation as resolved.
Show resolved Hide resolved
end

# == Schema Information
Expand Down
25 changes: 25 additions & 0 deletions spec/blueprints/contribution_blueprint_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,29 @@
result = ContributionBlueprint.render(contribution, show_view_path: true, current_user: user)
expect(JSON.parse(result)['view_path']).to eq(expected_path)
end

it 'can serialize a community resource as a contribution' do
resource = create(:community_resource)
# The test database defaults to having no contact methods, so we need at least one
default_contact_method = create(:contact_method)
expected_result = {
"id" => resource.id, # not bothering to save the record in this test
"category_tags" => [],
"contact_types" => [{"id" => default_contact_method.id, "name" => "Call"}],
"contribution_type" => "Community Resource",
"created_at" => resource.created_at.to_f * 1000,
"description" => "Food for the revolution",
"inexhaustible" => true,
"location" => nil,
"match_path" => nil,
"name" => "Free breakfast for School Children Program",
"person" => nil,
Comment on lines +90 to +95
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@exbinary pointed out how hashes like this to test blobs of JSON are fragile since small changes can then require lots of edits

"service_area" => nil,
"title" => "Food for the revolution",
"urgency" => {"id" => 4, "name" => "Anytime"},
"view_path" => nil
}
result = ContributionBlueprint.render(resource, current_user: user)
expect(JSON.parse(result)).to eq(expected_result)
end
end