From b17387a17669bfc9afce7435653cd8c29c686999 Mon Sep 17 00:00:00 2001 From: Azul Date: Sat, 12 Jul 2014 09:12:48 +0200 Subject: some cleanup of the messages api and cuke feature --- .../controller_extension/json_responses.rb | 29 +++++++++ app/controllers/v1/messages_controller.rb | 4 +- app/models/message.rb | 4 ++ app/models/user.rb | 7 +- config/initializers/add_controller_methods.rb | 1 + features/messages.feature | 74 ++++++++++++++++++++++ features/step_definitions/api_steps.rb | 8 +-- features/step_definitions/messages_steps.rb | 32 ++++++++++ features/support/hooks.rb | 14 ++++ test/factories.rb | 4 ++ 10 files changed, 166 insertions(+), 11 deletions(-) create mode 100644 app/controllers/controller_extension/json_responses.rb create mode 100644 features/messages.feature create mode 100644 features/step_definitions/messages_steps.rb diff --git a/app/controllers/controller_extension/json_responses.rb b/app/controllers/controller_extension/json_responses.rb new file mode 100644 index 0000000..da1ae58 --- /dev/null +++ b/app/controllers/controller_extension/json_responses.rb @@ -0,0 +1,29 @@ +module ControllerExtension::JsonResponses + extend ActiveSupport::Concern + + private + + def success(key) + json_message :success, key + end + + def error(key) + json_message :error, key + end + + def json_message(type, key) + long_key = "#{controller_string}.#{action_string}.#{key}" + { type => key.to_s, + :message => I18n.t(long_key, cascade: true) } + end + + def controller_string + self.class.name.underscore. + sub(/_controller$/, ''). + sub(/^v\d\//, '') + end + + def action_string + params[:action] + end +end diff --git a/app/controllers/v1/messages_controller.rb b/app/controllers/v1/messages_controller.rb index a9b93a9..a496378 100644 --- a/app/controllers/v1/messages_controller.rb +++ b/app/controllers/v1/messages_controller.rb @@ -11,9 +11,9 @@ module V1 if message = Message.find(params[:id]) message.mark_as_read_by(current_user) message.save - render json: true + render json: success(:marked_as_read) else - render json: false + render json: error(:not_found), status: :not_found end end diff --git a/app/models/message.rb b/app/models/message.rb index 424f094..2478f3f 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -26,4 +26,8 @@ class Message < CouchRest::Model::Base def unread_by?(user) user_ids_to_show.include?(user.id) end + + def as_json(*args, &block) + {"id" => id, "text" => text}.as_json(*args, &block) + end end diff --git a/app/models/user.rb b/app/models/user.rb index 6bc5841..9ac7d3d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -92,12 +92,9 @@ class User < CouchRest::Model::Base Ticket.for_user(self).limit(count).all #defaults to having most recent updated first end - def messages(unseen = true) + def messages #TODO for now this only shows unseen messages. Will we ever want seen ones? Is it necessary to store? - - # we don't want to emit all the userids associated with a message, so only emit id and text. - Message.by_user_ids_to_show.key(self.id).map { |message| [message.id, message.text] } - + Message.by_user_ids_to_show.key(self.id) end # DEPRECATED diff --git a/config/initializers/add_controller_methods.rb b/config/initializers/add_controller_methods.rb index f107544..4ad4213 100644 --- a/config/initializers/add_controller_methods.rb +++ b/config/initializers/add_controller_methods.rb @@ -2,5 +2,6 @@ ActiveSupport.on_load(:application_controller) do include ControllerExtension::Authentication include ControllerExtension::TokenAuthentication include ControllerExtension::Flash + include ControllerExtension::JsonResponses include ControllerExtension::Errors end diff --git a/features/messages.feature b/features/messages.feature new file mode 100644 index 0000000..34c0892 --- /dev/null +++ b/features/messages.feature @@ -0,0 +1,74 @@ +Feature: Receive messages for the user + + In order to stay in touch with the provider + As an authenticated user + I want to receive messages from the provider + + Background: + Given I authenticated + Given I set headers: + | Accept | application/json | + | Content-Type | application/json | + | Authorization | Token token="MY_AUTH_TOKEN" | + + Scenario: There are no messages yet + When I send a GET request to "/1/messages.json" + Then the response status should be "200" + And the response should be: + """ + [] + """ + + Scenario: Fetch the unread messages + Given there is a message for me with: + | id | 1a2b3c4d | + | text | Your provider says hi ! | + When I send a GET request to "/1/messages.json" + Then the response status should be "200" + And the response should be: + """ + [{ + "id": "1a2b3c4d", + "text": "Your provider says hi !" + }] + """ + + Scenario: Send unread messages until marked as read + Given there is a message for me + And I have sent a GET request to "/1/messages.json" + When I send a GET request to "/1/messages.json" + Then the response status should be "200" + And the response should include that message + + Scenario: Mark message as read + Given there is a message for me with: + | id | 1a2b3c4d | + When I send a PUT request to "/1/messages/1a2b3c4d.json" + Then the response status should be "200" + And the response should be: + """ + { "success": "marked as read", + "message": "The message has been marked as read" } + """ + And that message should be marked as read + + Scenario: Message not found + When I send a PUT request to "/1/messages/1a2b3c4d.json" + Then the response status should be "404" + And the response should be: + """ + { "error": "not found", + "message": "The message could not be found" } + """ + + Scenario: Do not send read messages + Given there is a message for me + And that message is marked as read + When I send a GET request to "/1/messages.json" + Then the response status should be "200" + And the response should be: + """ + [] + """ + + diff --git a/features/step_definitions/api_steps.rb b/features/step_definitions/api_steps.rb index a4f369c..7188694 100644 --- a/features/step_definitions/api_steps.rb +++ b/features/step_definitions/api_steps.rb @@ -13,8 +13,9 @@ end Given /^I set headers:$/ do |headers| headers.rows_hash.each do |key,value| - value.sub!('MY_AUTH_TOKEN', @my_auth_token.to_s) if @my_auth_token - header key, value + replace = value.dup + replace.sub!('MY_AUTH_TOKEN', @my_auth_token.to_s) if @my_auth_token + header key, replace end end @@ -36,7 +37,7 @@ When /^I digest\-authenticate as the user "(.*?)" with the password "(.*?)"$/ do digest_authorize user, pass end -When /^I send a (GET|POST|PUT|DELETE) request (?:for|to) "([^"]*)"(?: with the following:)?$/ do |*args| +When /^I (?:have sent|send) a (GET|POST|PUT|DELETE) request (?:for|to) "([^"]*)"(?: with the following:)?$/ do |*args| request_type = args.shift path = args.shift input = args.shift @@ -50,7 +51,6 @@ When /^I send a (GET|POST|PUT|DELETE) request (?:for|to) "([^"]*)"(?: with the f request_opts[:input] = input end end - request path, request_opts end diff --git a/features/step_definitions/messages_steps.rb b/features/step_definitions/messages_steps.rb new file mode 100644 index 0000000..30bc7c3 --- /dev/null +++ b/features/step_definitions/messages_steps.rb @@ -0,0 +1,32 @@ +Given /^there is a message for me$/ do + @message = FactoryGirl.create :message, user_ids_to_show: [@user.id] +end + +Given /^there is a message for me with:$/ do |options| + attributes = options.rows_hash + attributes.merge! user_ids_to_show: [@user.id] + if old_message = Message.find(attributes['id']) + old_message.destroy + end + @message = FactoryGirl.create :message, attributes +end + +Given(/^that message is marked as read$/) do + @message.mark_as_read_by(@user) + @message.save +end + +Then /^the response should (not)?\s?include that message$/ do |negative| + json = JSON.parse(last_response.body) + message = json.detect{|message| message['id'] == @message.id} + if negative.present? + assert !message + else + assert_equal @message.text, message['text'] + end +end + +Then /^that message should be marked as read$/ do + assert @message.reload.read_by? @user + assert !@message.unread_by?(@user) +end diff --git a/features/support/hooks.rb b/features/support/hooks.rb index 19928d8..f11e602 100644 --- a/features/support/hooks.rb +++ b/features/support/hooks.rb @@ -5,6 +5,7 @@ After '@tempfile' do end end +# store end of server log for failing scenarios After do |scenario| if scenario.failed? logfile_path = Rails.root + 'tmp' @@ -16,3 +17,16 @@ After do |scenario| end end end + +# clear all records we created +After do + names = self.instance_variables.reject do |v| + v.to_s.starts_with?('@_') + end + names.each do |name| + record = self.instance_variable_get name + if record.is_a?(CouchRest::Model::Base) && record.persisted? + record.reload && record.destroy + end + end +end diff --git a/test/factories.rb b/test/factories.rb index a96d48c..e16c738 100644 --- a/test/factories.rb +++ b/test/factories.rb @@ -47,4 +47,8 @@ FactoryGirl.define do -----END PGP PUBLIC KEY BLOCK----- EOPGP end + + factory :message do + text Faker::Lorem.paragraph + end end -- cgit v1.2.3