From 4854465bcc977e58a015445b3891c4b69d0685c5 Mon Sep 17 00:00:00 2001 From: fauno Date: Sat, 3 Aug 2019 14:28:04 -0300 Subject: [PATCH] las piratas se pueden suscribir a notificaciones --- Gemfile | 2 + Gemfile.lock | 5 +++ .../webpush_subscriptions_controller.rb | 26 +++++++++++++ app/models/pirata.rb | 2 + app/models/webpush_subscription.rb | 9 +++++ .../create.json.jbuilder | 3 ++ config/routes.rb | 2 + ...0803170257_create_webpush_subscriptions.rb | 16 ++++++++ .../webpush_subscriptions_controller_test.rb | 39 +++++++++++++++++++ test/factories/webpush_subscription.rb | 10 +++++ test/models/webpush_subscription_test.rb | 20 ++++++++++ 11 files changed, 134 insertions(+) create mode 100644 app/controllers/webpush_subscriptions_controller.rb create mode 100644 app/models/webpush_subscription.rb create mode 100644 app/views/webpush_subscriptions/create.json.jbuilder create mode 100644 db/migrate/20190803170257_create_webpush_subscriptions.rb create mode 100644 test/controllers/webpush_subscriptions_controller_test.rb create mode 100644 test/factories/webpush_subscription.rb create mode 100644 test/models/webpush_subscription_test.rb diff --git a/Gemfile b/Gemfile index b47d55b..e54450d 100644 --- a/Gemfile +++ b/Gemfile @@ -18,6 +18,8 @@ gem 'jbuilder', '~> 2.5' # Use ActiveModel has_secure_password gem 'bcrypt', '~> 3.1.7' +gem 'validate_url' + # Use ActiveStorage variant # gem 'mini_magick', '~> 4.8' diff --git a/Gemfile.lock b/Gemfile.lock index 39cc73e..31049c0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -95,6 +95,7 @@ GEM coderay (~> 1.1.0) method_source (~> 0.9.0) psych (3.1.0) + public_suffix (4.0.0) puma (3.12.1) rack (2.0.7) rack-cors (1.0.3) @@ -157,6 +158,9 @@ GEM tzinfo (1.2.5) thread_safe (~> 0.1) unicode-display_width (1.5.0) + validate_url (1.0.8) + activemodel (>= 3.0.0) + public_suffix websocket-driver (0.7.0) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.3) @@ -180,6 +184,7 @@ DEPENDENCIES spring spring-watcher-listen (~> 2.0.0) sqlite3 + validate_url yard RUBY VERSION diff --git a/app/controllers/webpush_subscriptions_controller.rb b/app/controllers/webpush_subscriptions_controller.rb new file mode 100644 index 0000000..43fb5a7 --- /dev/null +++ b/app/controllers/webpush_subscriptions_controller.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +# Recibe suscripciones webpush +class WebpushSubscriptionsController < ApplicationController + before_action :authenticate! + + def create + @subscription = current_pirata.webpush_subscriptions + .build(subscriptions_params) + + if @subscription.save + render status: :created + else + # El único error que podemos tener es que la subscripción ya esté + # hecha, con lo que no hace falta que la volvamos a crear. + render status: :no_content + end + end + + private + + def subscriptions_params + params.require(:webpush_subscription) + .permit(:endpoint, :auth, :p256dh) + end +end diff --git a/app/models/pirata.rb b/app/models/pirata.rb index 638096a..914a410 100644 --- a/app/models/pirata.rb +++ b/app/models/pirata.rb @@ -7,6 +7,8 @@ class Pirata < ApplicationRecord # Y tener posiciones has_many :posiciones + has_many :webpush_subscriptions + # Puede participar en barcas has_many :tripulaciones has_many :barcas, through: :tripulaciones diff --git a/app/models/webpush_subscription.rb b/app/models/webpush_subscription.rb new file mode 100644 index 0000000..7d0051d --- /dev/null +++ b/app/models/webpush_subscription.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +# Gestiona las suscripciones por webpush +class WebpushSubscription < ApplicationRecord + belongs_to :pirata + validates :endpoint, url: true + validates_uniqueness_of :auth, scope: %i[p256dh endpoint], + case_sensitive: false +end diff --git a/app/views/webpush_subscriptions/create.json.jbuilder b/app/views/webpush_subscriptions/create.json.jbuilder new file mode 100644 index 0000000..625f72c --- /dev/null +++ b/app/views/webpush_subscriptions/create.json.jbuilder @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +# Empty response diff --git a/config/routes.rb b/config/routes.rb index c3f761f..1e0ddb7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -4,6 +4,8 @@ Rails.application.routes.draw do get '/piratas/yo', to: 'piratas#yo' # No queremos un índice de piratas resources :piratas, only: %i[create] + # Solo se pueden crear suscripciones + resources :webpush_subscriptions, only: %i[create] # Podemos crear barcas y dentro de ellas consensos resources :barcas, only: %i[index show create update destroy] do # Podemos crear consensos pero no modificarlos diff --git a/db/migrate/20190803170257_create_webpush_subscriptions.rb b/db/migrate/20190803170257_create_webpush_subscriptions.rb new file mode 100644 index 0000000..32394a2 --- /dev/null +++ b/db/migrate/20190803170257_create_webpush_subscriptions.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# Crear las suscripciones por webpush +class CreateWebpushSubscriptions < ActiveRecord::Migration[5.2] + def change + create_table :webpush_subscriptions do |t| + t.timestamps + t.belongs_to :pirata, index: true + t.string :auth + t.string :p256dh + t.string :endpoint + + t.index %i[auth p256dh endpoint], unique: true + end + end +end diff --git a/test/controllers/webpush_subscriptions_controller_test.rb b/test/controllers/webpush_subscriptions_controller_test.rb new file mode 100644 index 0000000..7581bb2 --- /dev/null +++ b/test/controllers/webpush_subscriptions_controller_test.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +class PiratasControllerTest < ActionDispatch::IntegrationTest + setup do + @pirata = create :pirata + @auth = { Authorization: ActionController::HttpAuthentication::Basic + .encode_credentials(@pirata.email, @pirata.password) } + end + + test 'se pueden crear' do + subscription = build :webpush_subscription + + post webpush_subscriptions_url, as: :json, headers: @auth, + params: { + webpush_subscription: { + auth: subscription.auth, + p256dh: subscription.p256dh, + endpoint: subscription.endpoint + } + } + + assert_equal 201, @response.status + end + + test 'no se pueden crear duplicadas' do + subscription = create :webpush_subscription + + post webpush_subscriptions_url, as: :json, headers: @auth, + params: { + webpush_subscription: { + auth: subscription.auth, + p256dh: subscription.p256dh, + endpoint: subscription.endpoint + } + } + + assert_equal 204, @response.status + end +end diff --git a/test/factories/webpush_subscription.rb b/test/factories/webpush_subscription.rb new file mode 100644 index 0000000..507a954 --- /dev/null +++ b/test/factories/webpush_subscription.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :webpush_subscription do + pirata + auth { SecureRandom.hex } + p256dh { SecureRandom.hex } + endpoint { "https://#{SecureRandom.hex}.org/endpoint" } + end +end diff --git a/test/models/webpush_subscription_test.rb b/test/models/webpush_subscription_test.rb new file mode 100644 index 0000000..53e177f --- /dev/null +++ b/test/models/webpush_subscription_test.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class WebpushSubscriptionTest < ActiveSupport::TestCase + test 'se pueden crear' do + subscription = create :webpush_subscription + + assert subscription.valid? + end + + test 'no se pueden crear duplicadas' do + subscription = create :webpush_subscription + subscription2 = build :webpush_subscription, + pirata: subscription.pirata, + auth: subscription.auth, + p256dh: subscription.p256dh, + endpoint: subscription.endpoint + + assert subscription2.invalid? + end +end