|
| 1 | +require 'spec_helper' |
| 2 | +require 'test_components' |
| 3 | +require 'rspec-steps' |
| 4 | + |
| 5 | + |
| 6 | +describe "while loading", js: true do |
| 7 | + |
| 8 | + before(:all) do |
| 9 | + ReactiveRecord::Operations::Fetch.class_eval do |
| 10 | + def self.semaphore |
| 11 | + @semaphore ||= Mutex.new |
| 12 | + end |
| 13 | + validate { self.class.semaphore.synchronize { true } } |
| 14 | + end |
| 15 | + require 'pusher' |
| 16 | + require 'pusher-fake' |
| 17 | + Pusher.app_id = "MY_TEST_ID" |
| 18 | + Pusher.key = "MY_TEST_KEY" |
| 19 | + Pusher.secret = "MY_TEST_SECRET" |
| 20 | + require "pusher-fake/support/base" |
| 21 | + |
| 22 | + Hyperstack.configuration do |config| |
| 23 | + config.transport = :pusher |
| 24 | + config.channel_prefix = "synchromesh" |
| 25 | + config.opts = {app_id: Pusher.app_id, key: Pusher.key, secret: Pusher.secret}.merge(PusherFake.configuration.web_options) |
| 26 | + end |
| 27 | + end |
| 28 | + |
| 29 | + before(:each) do |
| 30 | + client_option raise_on_js_errors: :off |
| 31 | + |
| 32 | + # spec_helper resets the policy system after each test so we have to setup |
| 33 | + # before each test |
| 34 | + stub_const 'TestApplication', Class.new |
| 35 | + stub_const 'TestApplicationPolicy', Class.new |
| 36 | + TestApplicationPolicy.class_eval do |
| 37 | + always_allow_connection |
| 38 | + regulate_all_broadcasts { |policy| policy.send_all } |
| 39 | + allow_change(to: :all, on: [:create, :update, :destroy]) { true } |
| 40 | + end |
| 41 | + # size_window(:small, :portrait) |
| 42 | + FactoryBot.create(:user, first_name: 'Lily', last_name: 'DaDog') |
| 43 | + FactoryBot.create(:user, first_name: 'Coffee', last_name: 'Boxer') |
| 44 | + end |
| 45 | + |
| 46 | + it "will display the while loading message for a fetch within a nested component" do |
| 47 | + ReactiveRecord::Operations::Fetch.semaphore.synchronize do |
| 48 | + mount "WhileLoadingTester", {}, no_wait: true do |
| 49 | + class MyNestedGuy < HyperComponent |
| 50 | + render(SPAN) do |
| 51 | + "#{User.find_by_first_name('Lily').last_name} is a dog" |
| 52 | + end |
| 53 | + end |
| 54 | + class WhileLoadingTester < HyperComponent |
| 55 | + include Hyperstack::Component::WhileLoading |
| 56 | + render do |
| 57 | + if resources_loaded? |
| 58 | + DIV do |
| 59 | + MyNestedGuy {} |
| 60 | + end |
| 61 | + else |
| 62 | + SPAN { 'loading...' } |
| 63 | + end |
| 64 | + end |
| 65 | + end |
| 66 | + end |
| 67 | + expect(page).to have_content('loading...') |
| 68 | + expect(page).not_to have_content('is a dog', wait: 0) |
| 69 | + end |
| 70 | + expect(page).to have_content('DaDog is a dog') |
| 71 | + expect(page).not_to have_content('loading...', wait: 0) |
| 72 | + end |
| 73 | + |
| 74 | + it "will display the while loading message for a fetch within a nested component when attached to that component" do |
| 75 | + ReactiveRecord::Operations::Fetch.semaphore.synchronize do |
| 76 | + mount "WhileLoadingTester", {}, no_wait: true do |
| 77 | + class MyNestedGuy < HyperComponent |
| 78 | + render(SPAN) do |
| 79 | + "#{User.find_by_first_name('Lily').last_name} is a dog" |
| 80 | + end |
| 81 | + end |
| 82 | + class WhileLoadingTester < HyperComponent |
| 83 | + include Hyperstack::Component::WhileLoading |
| 84 | + render(DIV) do |
| 85 | + if resources_loaded? |
| 86 | + MyNestedGuy {} |
| 87 | + else |
| 88 | + SPAN { 'loading...' } |
| 89 | + end |
| 90 | + end |
| 91 | + end |
| 92 | + end |
| 93 | + expect(page).to have_content('loading...') |
| 94 | + expect(page).not_to have_content('is a dog', wait: 0) |
| 95 | + end |
| 96 | + expect(page).to have_content('DaDog is a dog') |
| 97 | + expect(page).not_to have_content('loading...', wait: 0) |
| 98 | + end |
| 99 | + |
| 100 | + it "The inner most while_loading will display only" do |
| 101 | + ReactiveRecord::Operations::Fetch.semaphore.synchronize do |
| 102 | + mount "WhileLoadingTester", {}, no_wait: true do |
| 103 | + class MyNestedGuy < HyperComponent |
| 104 | + include Hyperstack::Component::WhileLoading |
| 105 | + render do |
| 106 | + if resources_loaded? |
| 107 | + DIV { "#{User.find_by_first_name('Lily').last_name} is a dog" } |
| 108 | + else |
| 109 | + SPAN { 'loading...' } |
| 110 | + end |
| 111 | + end |
| 112 | + end |
| 113 | + class WhileLoadingTester < HyperComponent |
| 114 | + include Hyperstack::Component::WhileLoading |
| 115 | + render do |
| 116 | + if resources_loaded? |
| 117 | + DIV do |
| 118 | + MyNestedGuy {} |
| 119 | + end |
| 120 | + else |
| 121 | + SPAN { 'i should not display' } |
| 122 | + end |
| 123 | + end |
| 124 | + end |
| 125 | + end |
| 126 | + expect(page).to have_content('loading...') |
| 127 | + expect(page).not_to have_content('is a dog', wait: 0) |
| 128 | + end |
| 129 | + expect(page).to have_content('DaDog is a dog') |
| 130 | + expect(page).not_to have_content('i should not display', wait: 0) |
| 131 | + end |
| 132 | + |
| 133 | + # it "while loading can take a string param instead of a block" do |
| 134 | + # ReactiveRecord::Operations::Fetch.semaphore.synchronize do |
| 135 | + # mount "WhileLoadingTester", {}, no_wait: true do |
| 136 | + # class WhileLoadingTester < HyperComponent |
| 137 | + # render do |
| 138 | + # DIV do |
| 139 | + # User.find_by_first_name('Lily').last_name |
| 140 | + # end |
| 141 | + # .while_loading 'loading...' |
| 142 | + # end |
| 143 | + # end |
| 144 | + # end |
| 145 | + # expect(page).to have_content('loading...') |
| 146 | + # expect(page).not_to have_content('DaDog', wait: 0) |
| 147 | + # end |
| 148 | + # expect(page).to have_content('DaDog') |
| 149 | + # expect(page).not_to have_content('loading...', wait: 0) |
| 150 | + # end |
| 151 | + # |
| 152 | + # it "while loading can take an element param instead of a block" do |
| 153 | + # ReactiveRecord::Operations::Fetch.semaphore.synchronize do |
| 154 | + # mount "WhileLoadingTester", {}, no_wait: true do |
| 155 | + # class WhileLoadingTester < HyperComponent |
| 156 | + # render do |
| 157 | + # DIV do |
| 158 | + # User.find_by_first_name('Lily').last_name |
| 159 | + # end |
| 160 | + # .while_loading(DIV { 'loading...' }) |
| 161 | + # end |
| 162 | + # end |
| 163 | + # end |
| 164 | + # expect(page).to have_content('loading...') |
| 165 | + # expect(page).not_to have_content('DaDog', wait: 0) |
| 166 | + # end |
| 167 | + # expect(page).to have_content('DaDog') |
| 168 | + # expect(page).not_to have_content('loading...', wait: 0) |
| 169 | + # end |
| 170 | + # |
| 171 | + # it "achieving while_loading behavior with state variables" do |
| 172 | + # ReactiveRecord::Operations::Fetch.semaphore.synchronize do |
| 173 | + # mount "WhileLoadingTester", {}, no_wait: true do |
| 174 | + # class MyComponent < HyperComponent |
| 175 | + # render do |
| 176 | + # SPAN { 'loading...' } |
| 177 | + # end |
| 178 | + # end |
| 179 | + # |
| 180 | + # class WhileLoadingTester < HyperComponent |
| 181 | + # |
| 182 | + # before_mount do |
| 183 | + # ReactiveRecord.load do |
| 184 | + # User.find_by_first_name('Lily').last_name |
| 185 | + # end.then do |last_name| |
| 186 | + # mutate @last_name = last_name |
| 187 | + # end |
| 188 | + # end |
| 189 | + # |
| 190 | + # render do |
| 191 | + # if @last_name |
| 192 | + # DIV { @last_name } |
| 193 | + # else |
| 194 | + # MyComponent {} |
| 195 | + # end |
| 196 | + # end |
| 197 | + # end |
| 198 | + # end |
| 199 | + # expect(page).to have_content('loading...') |
| 200 | + # expect(page).not_to have_content('DaDog', wait: 0) |
| 201 | + # end |
| 202 | + # expect(page).to have_content('DaDog') |
| 203 | + # expect(page).not_to have_content('loading...', wait: 0) |
| 204 | + # end |
| 205 | + # |
| 206 | + # it "while loading display an application defined element" do |
| 207 | + # ReactiveRecord::Operations::Fetch.semaphore.synchronize do |
| 208 | + # mount "WhileLoadingTester", {}, no_wait: true do |
| 209 | + # class MyComponent < HyperComponent |
| 210 | + # render do |
| 211 | + # SPAN { 'loading...' } |
| 212 | + # end |
| 213 | + # end |
| 214 | + # class WhileLoadingTester < HyperComponent |
| 215 | + # render do |
| 216 | + # DIV do |
| 217 | + # User.find_by_first_name('Lily').last_name |
| 218 | + # end |
| 219 | + # .while_loading do |
| 220 | + # MyComponent {} |
| 221 | + # end |
| 222 | + # end |
| 223 | + # end |
| 224 | + # end |
| 225 | + # expect(page).to have_content('loading...') |
| 226 | + # expect(page).not_to have_content('DaDog', wait: 0) |
| 227 | + # end |
| 228 | + # expect(page).to have_content('DaDog') |
| 229 | + # expect(page).not_to have_content('loading...', wait: 0) |
| 230 | + # end |
| 231 | + |
| 232 | + it "while loading works when number of children changes (i.e. relationships)" do |
| 233 | + ReactiveRecord::Operations::Fetch.semaphore.synchronize do |
| 234 | + mount "WhileLoadingTester", {}, no_wait: true do |
| 235 | + class WhileLoadingTester < HyperComponent |
| 236 | + include Hyperstack::Component::WhileLoading |
| 237 | + render do |
| 238 | + if resources_loaded? |
| 239 | + UL { User.each { |user| LI { user.last_name } } } |
| 240 | + else |
| 241 | + 'loading...' |
| 242 | + end |
| 243 | + end |
| 244 | + end |
| 245 | + end |
| 246 | + expect(page).to have_content('loading...') |
| 247 | + expect(page).not_to have_content('DaDog', wait: 0) |
| 248 | + expect(page).not_to have_content('Boxer', wait: 0) |
| 249 | + end |
| 250 | + expect(page).to have_content('DaDog') |
| 251 | + expect(page).to have_content('Boxer') |
| 252 | + expect(page).not_to have_content('loading...', wait: 0) |
| 253 | + end |
| 254 | + |
| 255 | + |
| 256 | + it "will display the while loading message on condition" do |
| 257 | + isomorphic do |
| 258 | + class FetchNow < Hyperstack::ServerOp |
| 259 | + dispatch_to { TestApplication } |
| 260 | + end |
| 261 | + end |
| 262 | + mount "WhileLoadingTester", {}, no_wait: true do |
| 263 | + class MyNestedGuy < HyperComponent |
| 264 | + self.class.attr_reader :fetch |
| 265 | + receives(FetchNow) { mutate @fetch = true } |
| 266 | + render(SPAN) do |
| 267 | + if self.class.fetch |
| 268 | + User.find_by_first_name('Lily').last_name |
| 269 | + else |
| 270 | + 'no fetch yet chet' |
| 271 | + end |
| 272 | + end |
| 273 | + end |
| 274 | + class WhileLoadingTester < HyperComponent |
| 275 | + include Hyperstack::Component::WhileLoading |
| 276 | + render do |
| 277 | + if resources_loaded? |
| 278 | + DIV { MyNestedGuy {} } |
| 279 | + else |
| 280 | + SPAN { 'loading...' } |
| 281 | + end |
| 282 | + end |
| 283 | + end |
| 284 | + end |
| 285 | + expect(page).to have_content('no fetch yet chet') |
| 286 | + expect(page).not_to have_content('loading...', wait: 0) |
| 287 | + expect(page).not_to have_content('DaDog', wait: 0) |
| 288 | + ReactiveRecord::Operations::Fetch.semaphore.synchronize do |
| 289 | + FetchNow.run |
| 290 | + expect(page).to have_content('loading...') |
| 291 | + expect(page).not_to have_content('DaDog', wait: 0) |
| 292 | + expect(page).not_to have_content('no fetch yet chet', wait: 0) |
| 293 | + end |
| 294 | + expect(page).to have_content('DaDog') |
| 295 | + expect(page).not_to have_content('loading...', wait: 0) |
| 296 | + expect(page).not_to have_content('no fetch yet chet', wait: 0) |
| 297 | + end |
| 298 | + |
| 299 | +end |
0 commit comments