Merge branch 'main' into house
* main: (23 commits) Improve the flow for editing bubble titles Use path helpers in tests Revising access shouldn't do a replace turbo-action Split into new tests Update this test, too Adjust tests to match new behavior Reapply "Destroy equivalent filters upon resource removal" Revert "Destroy equivalent filters upon resource removal" Destroy equivalent filters upon resource removal Don't autocomplete Rework boosts form so you can enter any integer Pull out access_menu_tag Punt on removing filters for inaccessible buckets Can't see bubbles in buckets you've lost access to Users can remove themselves from buckets Fix redirect assertion Fix redirect assertion Submit form when toggling all-access + caching Unnecessary parens Can't revoke access to all-access bucket ...
This commit is contained in:
@@ -78,6 +78,7 @@
|
||||
--rotation: 45deg;
|
||||
|
||||
aspect-ratio: 6/9;
|
||||
border-radius: var(--bubble-shape);
|
||||
display: flex;
|
||||
font-size: 6cqi;
|
||||
inset: 70cqi 7cqi auto auto;
|
||||
@@ -86,22 +87,27 @@
|
||||
place-items: center;
|
||||
transform: rotate(var(--rotation));
|
||||
|
||||
span {
|
||||
|
||||
.boost__form {
|
||||
transform: rotate(calc(var(--rotation) * -1));
|
||||
}
|
||||
|
||||
form {
|
||||
block-size: 100%;
|
||||
display: grid;
|
||||
inline-size: 100%;
|
||||
.boost__btn {
|
||||
--btn-background: var(--bubble-color);
|
||||
--btn-border-radius: 50%;
|
||||
--btn-color: var(--color-ink-reversed);
|
||||
--btn-size: 0.5em;
|
||||
--btn-padding: 0.3em 0.5em;
|
||||
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.btn {
|
||||
--btn-background: transparent;
|
||||
--btn-color: var(--bubble-color);
|
||||
|
||||
appearance: none;
|
||||
.boost__input {
|
||||
color: var(--bubble-color);
|
||||
field-sizing: content;
|
||||
font-weight: 800;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&.boosting {
|
||||
@@ -210,15 +216,6 @@
|
||||
transition: transform 200ms ease-out;
|
||||
white-space: nowrap;
|
||||
z-index: 1;
|
||||
|
||||
&:has(.input:not([type="file"], [type="date"], select)) {
|
||||
border-radius: 2em;
|
||||
padding: 0.2em 0.5em;
|
||||
|
||||
.input {
|
||||
color: var(--bubble-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
.toggler--toggled {
|
||||
.toggler__visible-when-off {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.toggler__visible-when-on {
|
||||
display: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.toggler__visible-when-on {
|
||||
display: none;
|
||||
}
|
||||
@@ -2,6 +2,15 @@ class BoostsController < ApplicationController
|
||||
include BubbleScoped, BucketScoped
|
||||
|
||||
def create
|
||||
@bubble.boost!
|
||||
count = if params[:boost_count].to_i == @bubble.boosts_count
|
||||
@bubble.boosts_count + 1
|
||||
else
|
||||
params[:boost_count].to_i
|
||||
end
|
||||
@bubble.boost!(count)
|
||||
|
||||
respond_to do |format|
|
||||
format.turbo_stream
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -38,7 +38,7 @@ class BucketsController < ApplicationController
|
||||
end
|
||||
|
||||
def bucket_params
|
||||
params.expect(bucket: [ :name ])
|
||||
params.expect(bucket: [ :name, :all_access ]).with_defaults(all_access: false)
|
||||
end
|
||||
|
||||
def grantees
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
module AccessesHelper
|
||||
def access_menu_tag(bucket, &)
|
||||
tag.menu class: [ "flex flex-column gap margin-none pad txt-medium", { "toggler--toggled": bucket.all_access? } ], data: {
|
||||
controller: "filter toggle-class",
|
||||
filter_active_class: "filter--active", filter_selected_class: "selected",
|
||||
toggle_class_toggle_class: "toggler--toggled" }, &
|
||||
end
|
||||
|
||||
def access_toggles_for(users, selected:)
|
||||
render partial: "buckets/access_toggle",
|
||||
collection: users, as: :user,
|
||||
locals: { selected: selected },
|
||||
cached: ->(user) { [ user, selected ] }
|
||||
end
|
||||
end
|
||||
@@ -5,10 +5,13 @@ module Bubble::Boostable
|
||||
scope :ordered_by_boosts, -> { order boosts_count: :desc }
|
||||
end
|
||||
|
||||
def boost!
|
||||
def boost!(count = 1)
|
||||
count = count.to_i
|
||||
count = 1 if count < 1
|
||||
|
||||
transaction do
|
||||
track_event :boosted
|
||||
increment! :boosts_count
|
||||
track_event :boosted, count: count
|
||||
update! boosts_count: count
|
||||
rescore
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,12 +15,20 @@ module Bucket::Accessible
|
||||
end
|
||||
|
||||
def revoke_from(users)
|
||||
destroy_by user: users
|
||||
destroy_by user: users unless proxy_association.owner.all_access?
|
||||
end
|
||||
end
|
||||
|
||||
has_many :users, through: :accesses
|
||||
|
||||
scope :all_access, -> { where(all_access: true) }
|
||||
|
||||
after_create -> { accesses.grant_to creator }
|
||||
after_save_commit :grant_access_to_everyone
|
||||
end
|
||||
|
||||
private
|
||||
def grant_access_to_everyone
|
||||
accesses.grant_to(account.users) if all_access_previously_changed?(to: true)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,5 +12,11 @@ module Filter::Resources
|
||||
kind = resource.class.model_name.plural
|
||||
send "#{kind}=", send(kind).without(resource)
|
||||
empty? ? destroy! : save!
|
||||
rescue ActiveRecord::RecordNotUnique
|
||||
destroy!
|
||||
end
|
||||
|
||||
def buckets
|
||||
creator.buckets.where id: bucket_ids
|
||||
end
|
||||
end
|
||||
|
||||
@@ -21,6 +21,8 @@ class User < ApplicationRecord
|
||||
validates_presence_of :email_address
|
||||
normalizes :email_address, with: ->(value) { value.strip.downcase }
|
||||
|
||||
after_create_commit :grant_access_to_buckets
|
||||
|
||||
scope :active, -> { where(active: true) }
|
||||
scope :alphabetically, -> { order("LOWER(name)") }
|
||||
|
||||
@@ -48,4 +50,8 @@ class User < ApplicationRecord
|
||||
def deactived_email_address
|
||||
email_address.sub(/@/, "-deactivated-#{SecureRandom.uuid}@")
|
||||
end
|
||||
|
||||
def grant_access_to_buckets
|
||||
Access.insert_all account.buckets.all_access.pluck(:id).collect { |bucket_id| { bucket_id: bucket_id, user_id: id } }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
toggle_class_toggle_class: "boosting",
|
||||
action: "animationend->toggle-class#toggle" },
|
||||
hidden: !bubble.boosts_count.positive? do %>
|
||||
<%= button_to bucket_bubble_boosts_path(bubble.bucket, bubble),
|
||||
class: "btn btn--plain",
|
||||
data: { action: "toggle-class#toggle" },
|
||||
form_class: "full-width" do %>
|
||||
<%= tag.span("+ #{bubble.boosts_count}") if bubble.boosts_count.positive? %>
|
||||
<%= form_with url: bucket_bubble_boosts_path(bubble.bucket, bubble),
|
||||
class: "boost__form",
|
||||
data: { action: "toggle-class#toggle" } do %>
|
||||
<%= text_field_tag :boost_count, bubble.boosts_count, min: 1, class: "input borderless boost__input", autocomplete: "off" %>
|
||||
<%= tag.button "+", class: "btn btn--plain boost__btn", type: :submit %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
<h1 class="bubble__title">
|
||||
<%= turbo_frame_tag bubble, :edit do %>
|
||||
<%= link_to bubble.title, edit_bucket_bubble_path(bubble.bucket, bubble), class: "txt-undecorated" %>
|
||||
|
||||
<div class="bubble__tags flex flex-wrap align-end justify-center gap-half txt-tight-lines">
|
||||
<%= render "bubbles/tags", bubble: bubble %>
|
||||
</div>
|
||||
<% end %>
|
||||
</h1>
|
||||
|
||||
<div class="bubble__tags flex flex-wrap align-end justify-center gap-half txt-tight-lines">
|
||||
<%= render "bubbles/tags", bubble: bubble %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bubble__shape"></div>
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
data-created-by-current-user-mine-class="comment--mine">
|
||||
<%# Template Dependency: comments/comment %>
|
||||
<%# Template Dependency: event_summaries/event_summary %>
|
||||
<%= render bubble.messages, cache: true %>
|
||||
<%= render bubble.messages, cached: true %>
|
||||
<%= render "comments/new", bubble: bubble %>
|
||||
</section>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<% bubble.tags.each do |tag| %>
|
||||
<%= link_to bubbles_path(@filter.to_params.merge(tag_ids: [ tag.id ])),
|
||||
class: "bubble__tag btn btn--plain fill-transparent min-width", style: "color: #{bubble.color}" do %>
|
||||
class: "bubble__tag btn btn--plain fill-transparent min-width", style: "color: #{bubble.color}", data: { turbo_frame: "_top" } do %>
|
||||
<span class="overflow-ellipsis"><%= tag.hashtag %></span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
<%= turbo_frame_tag @bubble, :edit do %>
|
||||
<%= form_with model: @bubble, url: bucket_bubble_path(@bubble.bucket, @bubble), class: "flex flex-column gap full-width", data: { controller: "form" } do |form| %>
|
||||
<%= form_with model: @bubble, url: bucket_bubble_path(@bubble.bucket, @bubble), class: "flex flex-column justify-center gap full-width", data: { controller: "form" } do |form| %>
|
||||
<%= form.label :title, class: "flex flex-column justify-center align-center" do %>
|
||||
<%= form.text_area :title, class: "input input--textara txt-align-center full-width borderless",
|
||||
required: true, rows: 5, autofocus: true, placeholder: "Name it…",
|
||||
data: { action: "keydown.ctrl+enter->form#submit:prevent keydown.meta+enter->form#submit:prevent keydown.esc->form#cancel focus->form#select" },
|
||||
style: "color: var(--spat-color); --input-border-radius: 0" %>
|
||||
<% end %>
|
||||
<%= form.submit "Save", hidden: true %>
|
||||
<%= form.button "Save", class: "btn btn--reversed txt-small center", type: :submit do %>
|
||||
<%= image_tag "check.svg", aria: { hidden: true }, size: 24 %>
|
||||
<span class="for-screen-reader">Save</span>
|
||||
<% end %>
|
||||
<%= link_to "Close editor and discard changes", bucket_bubble_path(@bubble.bucket, @bubble), data: { form_target: "cancel" }, hidden: true %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<li class="flex align-center gap-half margin-none unpad" data-value="<%= user.name.downcase %>">
|
||||
<figure class="avatar flex-item-no-shrink">
|
||||
<%= avatar_tag user, loading: :lazy %>
|
||||
</figure>
|
||||
|
||||
<div class="min-width">
|
||||
<div class="overflow-ellipsis">
|
||||
<strong><%= user.name %></strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="separator--horizontal flex-item-grow" style="--border-color: var(--color-subtle-dark); --border-style: dashed" aria-hidden="true">
|
||||
|
||||
<%= image_tag "check.svg", size: 20, class: "toggler__visible-when-on colorize--black flex-item-no-shrink", aria: { hidden: "true" } %>
|
||||
|
||||
<label class="switch toggler__visible-when-off flex-item-no-shrink">
|
||||
<%= check_box_tag "user_ids[]", user.id, selected, class: "switch__input", id: nil %>
|
||||
<span class="switch__btn round"></span>
|
||||
<span class="for-screen-reader">Give <%= user.name %> access</span>
|
||||
</label>
|
||||
</li>
|
||||
@@ -1,24 +0,0 @@
|
||||
<li class="flex align-center gap-half margin-none unpad" data-value="<%= user.name.downcase %>">
|
||||
<figure class="avatar flex-item-no-shrink">
|
||||
<%= avatar_tag user, loading: :lazy %>
|
||||
</figure>
|
||||
|
||||
<div class="min-width">
|
||||
<div class="overflow-ellipsis">
|
||||
<strong><%= user.name %></strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="separator--horizontal flex-item-grow" style="--border-color: var(--color-subtle-dark); --border-style: dashed" aria-hidden="true">
|
||||
|
||||
<% if user == Current.user %>
|
||||
<%= hidden_field_tag "user_ids[]", user.id, id: nil %>
|
||||
<%= image_tag "check.svg", size: 20, class: "colorize--black flex-item-no-shrink", aria: { hidden: "true" } %>
|
||||
<% else %>
|
||||
<label class="switch flex-item-no-shrink">
|
||||
<%= check_box_tag "user_ids[]", user.id, selected, class: "switch__input", id: nil %>
|
||||
<span class="switch__btn round"></span>
|
||||
<span class="for-screen-reader">Give <%= user.name %> access</span>
|
||||
</label>
|
||||
<% end %>
|
||||
</li>
|
||||
@@ -1,14 +0,0 @@
|
||||
<h1>Users on <%= @bucket.name %></h1>
|
||||
|
||||
<%= form_with url: bucket_access_path, method: :put do |form| %>
|
||||
<ul>
|
||||
<% Current.account.users.active.each do |user| %>
|
||||
<li>
|
||||
<%= check_box_tag "user_ids[]", user.id, @bucket.users.include?(user), id: nil, disabled: user == Current.user %>
|
||||
<%= user.name %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
<%= form.submit %>
|
||||
<% end %>
|
||||
@@ -17,7 +17,7 @@
|
||||
<% end %>
|
||||
|
||||
<div class="panel shadow center" style="--panel-size: 55ch;">
|
||||
<%= form_with model: @bucket, class: "flex flex-column gap txt-large", controller: "form" do |form| %>
|
||||
<%= form_with model: @bucket, class: "flex flex-column gap txt-large", data: { controller: "form" } do |form| %>
|
||||
<div class="flex align-center gap">
|
||||
<%= translation_button(:bucket_name) %>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
</div>
|
||||
|
||||
<section class="margin-block pad-inline fill-shade border-radius">
|
||||
<menu class="flex flex-column gap margin-none pad txt-medium" data-controller="filter" data-filter-active-class="filter--active" data-filter-selected-class="selected">
|
||||
<%= access_menu_tag @bucket do %>
|
||||
<li class="flex align-center gap margin-none">
|
||||
<figure class="avatar flex-item-no-shrink" style="--avatar-border-radius: 0; --avatar-size: 4ch;">
|
||||
<%= image_tag "everyone.svg", aria: { hidden: "true" }, class: "colorize--black" %>
|
||||
@@ -42,13 +42,11 @@
|
||||
|
||||
<hr class="separator--horizontal flex-item-grow" style="--border-color: var(--color-subtle-dark); --border-style: dashed" aria-hidden="true" />
|
||||
|
||||
<%= link_to nil, class: "btn--faux flex-inline", tabindex: "-1" do %>
|
||||
<label class="switch">
|
||||
<input type="checkbox" lass="switch__input">
|
||||
<span class="switch__btn round"></span>
|
||||
<span class="for-screen-reader">Give everyone access to this project</span>
|
||||
</label>
|
||||
<% end %>
|
||||
<label for="bucket_all_access" class="switch">
|
||||
<%= form.check_box :all_access, class: "switch__input", checked: @bucket.all_access?, data: { action: "change->toggle-class#toggle" } %>
|
||||
<span class="switch__btn round"></span>
|
||||
<span class="for-screen-reader">Give everyone access to this project</span>
|
||||
</label>
|
||||
</li>
|
||||
|
||||
<hr class="separator--horizontal full-width" style="--border-color: var(--color-subtle-dark);" aria-hidden="true" />
|
||||
@@ -58,15 +56,15 @@
|
||||
<% end %>
|
||||
|
||||
<div data-filter-target="list">
|
||||
<%= render partial: "buckets/user_toggle", collection: @selected_users, as: :user, locals: { selected: true } %>
|
||||
<%= access_toggles_for @selected_users, selected: true %>
|
||||
|
||||
<% if @selected_users.any? && @unselected_users.any? %>
|
||||
<hr class="separator full-width" style="--border-style: solid">
|
||||
<% end %>
|
||||
|
||||
<%= render partial: "buckets/user_toggle", collection: @unselected_users, as: :user, locals: { selected: false } %>
|
||||
<%= access_toggles_for @unselected_users, selected: false %>
|
||||
</div>
|
||||
</menu>
|
||||
<% end %>
|
||||
</section>
|
||||
|
||||
<button type="submit" id="log_in" class="btn btn--reversed center">
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddAllAccessToBucket < ActiveRecord::Migration[8.1]
|
||||
def change
|
||||
add_column :buckets, :all_access, :boolean, default: false, null: false
|
||||
end
|
||||
end
|
||||
Generated
+2
-1
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.0].define(version: 2024_11_26_232658) do
|
||||
ActiveRecord::Schema[8.1].define(version: 2024_12_09_223551) do
|
||||
create_table "accesses", force: :cascade do |t|
|
||||
t.integer "bucket_id", null: false
|
||||
t.integer "user_id", null: false
|
||||
@@ -116,6 +116,7 @@ ActiveRecord::Schema[8.0].define(version: 2024_11_26_232658) do
|
||||
t.string "name", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.boolean "all_access", default: false, null: false
|
||||
t.index ["account_id"], name: "index_buckets_on_account_id"
|
||||
t.index ["creator_id"], name: "index_buckets_on_creator_id"
|
||||
end
|
||||
|
||||
@@ -6,8 +6,20 @@ class BoostsControllerTest < ActionDispatch::IntegrationTest
|
||||
end
|
||||
|
||||
test "create" do
|
||||
boost_count = bubbles(:logo).boosts_count
|
||||
|
||||
assert_difference "bubbles(:logo).reload.boosts_count", +1 do
|
||||
post bucket_bubble_boosts_url(buckets(:writebook), bubbles(:logo), format: :turbo_stream)
|
||||
post bucket_bubble_boosts_url(buckets(:writebook), bubbles(:logo), params: { boost_count: boost_count }, format: :turbo_stream)
|
||||
end
|
||||
|
||||
assert_turbo_stream action: :update, target: dom_id(bubbles(:logo), :boosts)
|
||||
end
|
||||
|
||||
test "create with value" do
|
||||
boost_count = 10
|
||||
|
||||
assert_changes "bubbles(:logo).reload.boosts_count", to: boost_count do
|
||||
post bucket_bubble_boosts_url(buckets(:writebook), bubbles(:logo), params: { boost_count: boost_count }, format: :turbo_stream)
|
||||
end
|
||||
|
||||
assert_turbo_stream action: :update, target: dom_id(bubbles(:logo), :boosts)
|
||||
|
||||
@@ -49,4 +49,14 @@ class BubblesControllerTest < ActionDispatch::IntegrationTest
|
||||
assert_equal "moon.jpg", bubble.image.filename.to_s
|
||||
assert_equal [ tags(:mobile) ], bubble.tags
|
||||
end
|
||||
|
||||
test "users can only see bubbles in buckets they have access to" do
|
||||
get bucket_bubble_url(buckets(:writebook), bubbles(:logo))
|
||||
assert_response :success
|
||||
|
||||
buckets(:writebook).update! all_access: false
|
||||
buckets(:writebook).accesses.revoke_from users(:kevin)
|
||||
get bucket_bubble_url(buckets(:writebook), bubbles(:logo))
|
||||
assert_response :not_found
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,6 +37,20 @@ class BucketsControllerTest < ActionDispatch::IntegrationTest
|
||||
assert_redirected_to bubbles_path(bucket_ids: [ buckets(:writebook) ])
|
||||
assert_equal "Writebook bugs", buckets(:writebook).reload.name
|
||||
assert_equal users(:david, :jz), buckets(:writebook).users
|
||||
assert_not buckets(:writebook).all_access?
|
||||
end
|
||||
|
||||
test "update all access" do
|
||||
bucket = Current.set(session: sessions(:kevin)) do
|
||||
accounts("37s").buckets.create! name: "New bucket", all_access: false
|
||||
end
|
||||
assert_equal [ users(:kevin) ], bucket.users
|
||||
|
||||
patch bucket_url(bucket), params: { bucket: { name: "Bugs", all_access: true } }
|
||||
|
||||
assert_redirected_to bubbles_path(bucket_ids: [ bucket ])
|
||||
assert bucket.reload.all_access?
|
||||
assert_equal accounts("37s").users, bucket.users
|
||||
end
|
||||
|
||||
test "destroy" do
|
||||
|
||||
Vendored
+1
@@ -2,3 +2,4 @@ writebook:
|
||||
name: Writebook
|
||||
account: 37s
|
||||
creator: david
|
||||
all_access: true
|
||||
|
||||
Vendored
+3
@@ -1,2 +1,5 @@
|
||||
david:
|
||||
user: david
|
||||
|
||||
kevin:
|
||||
user: kevin
|
||||
|
||||
@@ -15,7 +15,7 @@ class BubbleTest < ActiveSupport::TestCase
|
||||
|
||||
test "boosting" do
|
||||
assert_difference %w[ bubbles(:logo).boosts_count bubbles(:logo).activity_score Event.count ], +1 do
|
||||
bubbles(:logo).boost!
|
||||
bubbles(:logo).boost!(bubbles(:logo).boosts_count+ 1)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ require "test_helper"
|
||||
|
||||
class BucketTest < ActiveSupport::TestCase
|
||||
test "revising access" do
|
||||
buckets(:writebook).update! all_access: false
|
||||
|
||||
buckets(:writebook).accesses.revise granted: users(:david, :jz), revoked: users(:kevin)
|
||||
assert_equal users(:david, :jz), buckets(:writebook).users
|
||||
|
||||
@@ -11,4 +13,21 @@ class BucketTest < ActiveSupport::TestCase
|
||||
buckets(:writebook).accesses.revoke_from users(:kevin)
|
||||
assert_not_includes buckets(:writebook).users.reload, users(:kevin)
|
||||
end
|
||||
|
||||
test "grants access to everyone after creation" do
|
||||
bucket = Current.set(session: sessions(:david)) do
|
||||
accounts("37s").buckets.create! name: "New bucket", all_access: true
|
||||
end
|
||||
assert_equal accounts("37s").users, bucket.users
|
||||
end
|
||||
|
||||
test "grants access to everyone after update" do
|
||||
bucket = Current.set(session: sessions(:david)) do
|
||||
accounts("37s").buckets.create! name: "New bucket"
|
||||
end
|
||||
assert_equal [ users(:david) ], bucket.users
|
||||
|
||||
bucket.update! all_access: true
|
||||
assert_equal accounts("37s").users, bucket.users.reload
|
||||
end
|
||||
end
|
||||
|
||||
@@ -41,6 +41,13 @@ class FilterTest < ActiveSupport::TestCase
|
||||
assert_equal [ bubbles(:shipping) ], filter.bubbles
|
||||
end
|
||||
|
||||
test "can't see bubbles in buckets that aren't accessible" do
|
||||
buckets(:writebook).update! all_access: false
|
||||
buckets(:writebook).accesses.revoke_from users(:david)
|
||||
|
||||
assert_empty users(:david).filters.new(bucket_ids: [ buckets(:writebook).id ]).bubbles
|
||||
end
|
||||
|
||||
test "turning into params" do
|
||||
expected = { indexed_by: "most_discussed", tag_ids: [ tags(:mobile).id ], assignee_ids: [ users(:jz).id ], filter_id: filters(:jz_assignments).id }
|
||||
assert_equal expected.stringify_keys, filters(:jz_assignments).to_params.to_h
|
||||
@@ -92,6 +99,15 @@ class FilterTest < ActiveSupport::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
test "duplicate filters are removed after a resource is destroyed" do
|
||||
users(:david).filters.create! tag_ids: [ tags(:mobile).id ], bucket_ids: [ buckets(:writebook).id ]
|
||||
users(:david).filters.create! tag_ids: [ tags(:mobile).id, tags(:web).id ], bucket_ids: [ buckets(:writebook).id ]
|
||||
|
||||
assert_difference "Filter.count", -1 do
|
||||
tags(:web).destroy!
|
||||
end
|
||||
end
|
||||
|
||||
test "summary" do
|
||||
assert_equal "Most discussed, tagged #Mobile, and assigned to JZ in all projects", filters(:jz_assignments).summary
|
||||
end
|
||||
|
||||
@@ -12,6 +12,16 @@ class UserTest < ActiveSupport::TestCase
|
||||
assert_equal user, User.authenticate_by(email_address: "victor@hey.com", password: "secret123456")
|
||||
end
|
||||
|
||||
test "creation gives access to all_access buckets" do
|
||||
user = User.create! \
|
||||
account: accounts("37s"),
|
||||
name: "Victor Cooper",
|
||||
email_address: "victor@hey.com",
|
||||
password: "secret123456"
|
||||
|
||||
assert_equal [ buckets(:writebook) ], user.buckets
|
||||
end
|
||||
|
||||
test "deactivate" do
|
||||
assert_changes -> { users(:jz).active? }, from: true, to: false do
|
||||
users(:jz).deactivate
|
||||
|
||||
Reference in New Issue
Block a user