Merge pull request #419 from colibri-software/api_auth

API auth
This commit is contained in:
Didier Lafforgue 2012-06-02 10:02:23 -07:00
commit 5f9c46b42c
29 changed files with 1947 additions and 15 deletions

View File

@ -7,15 +7,13 @@ module Locomotive
skip_before_filter :verify_authenticity_token
skip_load_and_authorize_resource
before_filter :require_account
before_filter :require_site
before_filter :set_locale
# before_filter :validate_site_membership
before_filter :set_current_thread_variables
self.responder = Locomotive::ActionController::Responder # custom responder
@ -23,6 +21,11 @@ module Locomotive
protected
def set_current_thread_variables
Thread.current[:account] = current_locomotive_account
Thread.current[:site] = current_site
end
def current_ability
@current_ability ||= Ability.new(current_locomotive_account, current_site)
end
@ -40,4 +43,4 @@ module Locomotive
end
end
end
end

View File

@ -2,11 +2,18 @@ module Locomotive
module Api
class ContentAssetsController < BaseController
load_and_authorize_resource :class => Locomotive::ContentAsset
def index
@content_assets = current_site.content_assets
respond_with(@content_assets)
end
def show
@content_asset = current_site.content_assets.find(params[:id])
respond_with(@content_asset)
end
def create
@content_asset = current_site.content_assets.create(params[:content_asset])
respond_with @content_asset, :location => main_app.locomotive_api_content_assets_url
@ -18,6 +25,12 @@ module Locomotive
respond_with @content_asset, :location => main_app.locomotive_api_content_assets_url
end
def destroy
@content_asset = current_site.content_assets.find(params[:id])
@content_asset.destroy
respond_with @content_asset
end
end
end
end

View File

@ -2,11 +2,18 @@ module Locomotive
module Api
class ContentTypesController < BaseController
load_and_authorize_resource :class => Locomotive::ContentType
def index
@content_types = current_site.content_types
respond_with(@content_types)
end
def show
@content_type = current_site.content_types.find(params[:id])
respond_with @content_type
end
def create
@content_type = current_site.content_types.create(params[:content_type])
respond_with @content_type, :location => main_app.locomotive_api_content_types_url
@ -18,6 +25,12 @@ module Locomotive
respond_with @content_type, :location => main_app.locomotive_api_content_types_url
end
def destroy
@content_type = current_site.content_types.find(params[:id])
@content_type.destroy
respond_with @content_type
end
end
end
end

View File

@ -3,7 +3,9 @@ module Locomotive
class CurrentSiteController < BaseController
def show
respond_with(current_site)
@site = current_site
authorize! :show, @site
respond_with(@site)
end
end

View File

@ -0,0 +1,49 @@
module Locomotive
module Api
class MembershipsController < BaseController
# It's an embedded document, so we'll just load manually
before_filter :load_membership, :only => [ :show, :update, :destroy ]
before_filter :load_memberships, :only => [ :index ]
authorize_resource :class => Locomotive::Membership
def index
respond_with(@memberships)
end
def show
respond_with(@membership)
end
def create
build_params = params[:membership].merge({ :role => 'author' }) # force author by default
@membership = current_site.memberships.create(build_params)
respond_with(@membership)
end
def update
@membership.update_attributes(params[:membership])
respond_with(@membership)
end
def destroy
@membership.destroy
respond_with(@membership)
end
protected
def load_membership
@membership ||= load_memberships.find(params[:id])
end
def load_memberships
@memberships ||= current_site.memberships
end
end
end
end

View File

@ -2,11 +2,18 @@ module Locomotive
module Api
class PagesController < BaseController
load_and_authorize_resource :class => Locomotive::Page
def index
@pages = current_site.pages.order_by([[:depth, :asc], [:position, :asc]])
respond_with(@pages)
end
def show
@page = current_site.pages.find(params[:id])
respond_with(@page)
end
def create
@page = current_site.pages.create(params[:page])
respond_with @page, :location => main_app.locomotive_api_pages_url
@ -18,6 +25,12 @@ module Locomotive
respond_with @page, :location => main_app.locomotive_api_pages_url
end
def destroy
@page = current_site.pages.find(params[:id])
@page.destroy
respond_with @page
end
end
end

View File

@ -0,0 +1,44 @@
module Locomotive
module Api
class SitesController < BaseController
load_and_authorize_resource :class => Locomotive::Site
# FIXME: the auto-loaded site won't pass authorization for show, update, or destroy
skip_load_and_authorize_resource :only => [ :show, :update, :destroy ]
def index
@sites = Locomotive::Site.all
respond_with(@sites)
end
def show
@site = Locomotive::Site.find(params[:id])
authorize! :show, @site
respond_with(@site)
end
def create
@site = Locomotive::Site.create(params[:site])
respond_with(@site)
end
def update
@site = Locomotive::Site.find(params[:id])
authorize! :update, @site
@site.update_attributes(params[:site])
respond_with @site
end
def destroy
@site = Locomotive::Site.find(params[:id])
authorize! :destroy, @site
@site.destroy
respond_with @site
end
end
end
end

View File

@ -2,11 +2,18 @@ module Locomotive
module Api
class SnippetsController < BaseController
load_and_authorize_resource :class => Locomotive::Snippet
def index
@snippets = current_site.snippets.all
respond_with(@snippets)
end
def show
@snippet = current_site.snippets.find(params[:id])
respond_with @snippet
end
def create
@snippet = current_site.snippets.create(params[:snippet])
respond_with @snippet, :location => main_app.locomotive_api_snippets_url
@ -18,6 +25,12 @@ module Locomotive
respond_with @snippet, :location => main_app.locomotive_api_snippets_url
end
def destroy
@snippet = current_site.snippets.find(params[:id])
@snippet.destroy
respond_with @snippet
end
end
end
end

View File

@ -2,11 +2,18 @@ module Locomotive
module Api
class ThemeAssetsController < BaseController
load_and_authorize_resource :class => Locomotive::ThemeAsset
def index
@theme_assets = current_site.theme_assets.all
respond_with(@theme_assets)
end
def show
@theme_asset = current_site.theme_assets.find(params[:id])
respond_with @theme_asset
end
def create
@theme_asset = current_site.theme_assets.create(params[:theme_asset])
respond_with @theme_asset, :location => main_app.locomotive_api_theme_assets_url
@ -18,6 +25,12 @@ module Locomotive
respond_with @theme_asset, :location => main_app.locomotive_api_theme_assets_url
end
def destroy
@theme_asset = current_site.theme_assets.find(params[:id])
@theme_asset.destroy
respond_with @theme_asset
end
end
end
end

View File

@ -37,6 +37,8 @@ module Locomotive
can :touch, Site do |site|
site == @site
end
can :read, ContentType
end
def setup_designer_permissions!

View File

@ -68,6 +68,10 @@ Rails.application.routes.draw do
resources :content_entries, :path => 'content_types/:slug/entries'
resources :sites
resources :memberships
resource :current_site, :controller => 'current_site'
end

View File

@ -0,0 +1,147 @@
Feature: Content Assets
In order to ensure content assets are not tampered with
As an admin, designer or author
I will be restricted based on my role
Background:
Given I have the site: "test site" set up
And I have the following content assets:
| id | file |
| 4f832c2cb0d86d3f42fffffe | 5k.png |
| 4f832c2cb0d86d3f42ffffff | 5k_2.png |
And I have a designer and an author
Scenario: As an unauthenticated user
Given I am not authenticated
When I do an API GET to content_assets.json
Then the JSON response at "error" should be "You need to sign in or sign up before continuing."
# listing content assets
Scenario: Accessing content assets as an Admin
Given I have an "admin" API token
When I do an API GET request to content_assets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
Scenario: Accessing content assets as a Designer
Given I have a "designer" API token
When I do an API GET request to content_assets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
Scenario: Accessing content assets as an Author
Given I have an "author" API token
When I do an API GET request to content_assets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
# showing content asset
Scenario: Accessing content asset as an Admin
Given I have an "admin" API token
When I do an API GET request to content_assets/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "filename" should be "5k.png"
Scenario: Accessing content asset as a Designer
Given I have a "designer" API token
When I do an API GET request to content_assets/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "filename" should be "5k.png"
Scenario: Accessing content asset as an Author
Given I have an "author" API token
When I do an API GET request to content_assets/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "filename" should be "5k.png"
# create content asset
Scenario: Creating new content asset as an Admin
Given I have an "admin" API token
When I do an API GET request to content_assets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do a multipart API POST to content_assets.json with base key "content_asset" and:
| source | assets/application.js |
When I do an API GET request to content_assets.json
Then the JSON response should be an array
And the JSON response should have 3 entries
And the JSON at "2/filename" should be "application.js"
Scenario: Creating new content asset as a Designer
Given I have a "designer" API token
When I do an API GET request to content_assets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do a multipart API POST to content_assets.json with base key "content_asset" and:
| source | assets/application.js |
When I do an API GET request to content_assets.json
Then the JSON response should be an array
And the JSON response should have 3 entries
And the JSON at "2/filename" should be "application.js"
Scenario: Creating new content asset as an Author
Given I have an "author" API token
When I do an API GET request to content_assets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do a multipart API POST to content_assets.json with base key "content_asset" and:
| source | assets/application.js |
When I do an API GET request to content_assets.json
Then the JSON response should be an array
And the JSON response should have 3 entries
And the JSON at "2/filename" should be "application.js"
# update content asset
Scenario: Updating content asset as an Admin
Given I have an "admin" API token
When I do a multipart API PUT to content_assets/4f832c2cb0d86d3f42fffffe.json with base key "content_asset" and:
| source | assets/main.css |
When I do an API GET request to content_assets/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "filename" should be "main.css"
Scenario: Updating content asset as a Designer
Given I have a "designer" API token
When I do a multipart API PUT to content_assets/4f832c2cb0d86d3f42fffffe.json with base key "content_asset" and:
| source | assets/main.css |
When I do an API GET request to content_assets/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "filename" should be "main.css"
Scenario: Updating content asset as an Author
Given I have a "author" API token
When I do a multipart API PUT to content_assets/4f832c2cb0d86d3f42fffffe.json with base key "content_asset" and:
| source | assets/main.css |
When I do an API GET request to content_assets/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "filename" should be "main.css"
# destroy content asset
Scenario: Destroying content asset as an Admin
Given I have an "admin" API token
When I do an API GET request to content_assets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do an API DELETE to content_assets/4f832c2cb0d86d3f42fffffe.json
When I do an API GET request to content_assets.json
Then the JSON response should be an array
And the JSON response should have 1 entry
Scenario: Destroying content asset as a Designer
Given I have a "designer" API token
When I do an API GET request to content_assets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do an API DELETE to content_assets/4f832c2cb0d86d3f42fffffe.json
When I do an API GET request to content_assets.json
Then the JSON response should be an array
And the JSON response should have 1 entry
Scenario: Deleting content asset as an Author
Given I have a "author" API token
When I do an API GET request to content_assets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do an API DELETE to content_assets/4f832c2cb0d86d3f42fffffe.json
When I do an API GET request to content_assets.json
Then the JSON response should be an array
And the JSON response should have 1 entry

View File

@ -0,0 +1,202 @@
Feature: Content Entries
In order to ensure content entries are not tampered with
As an admin, designer or author
I will be restricted based on my role
Background:
Given I have the site: "test site" set up
And I have a custom model named "Projects" with
| label | type | required |
| Name | string | true |
| Description | text | false |
And I have entries for "Projects" with
| id | name | description |
| 4f832c2cb0d86d3f42fffffe | Project 1 | The first project |
| 4f832c2cb0d86d3f42ffffff | Project 2 | The second project |
And I have a designer and an author
Scenario: As an unauthenticated user
Given I am not authenticated
When I do an API GET to content_types/projects/entries.json
Then the JSON response at "error" should be "You need to sign in or sign up before continuing."
# listing content entries
Scenario: Accessing content entries as an Admin
Given I have an "admin" API token
When I do an API GET request to content_types/projects/entries.json
Then the JSON response should be an array
And the JSON response should have 2 entries
Scenario: Accessing content entries as a Designer
Given I have a "designer" API token
When I do an API GET request to content_types/projects/entries.json
Then the JSON response should be an array
And the JSON response should have 2 entries
Scenario: Accessing content entries as an Author
Given I have an "author" API token
When I do an API GET request to content_types/projects/entries.json
Then the JSON response should be an array
And the JSON response should have 2 entries
# showing content entry
Scenario: Accessing content entry as an Admin
Given I have an "admin" API token
When I do an API GET request to content_types/projects/entries/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "name" should be "Project 1"
Scenario: Accessing content entry as a Designer
Given I have a "designer" API token
When I do an API GET request to content_types/projects/entries/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "name" should be "Project 1"
Scenario: Accessing content entry as an Author
Given I have an "author" API token
When I do an API GET request to content_types/projects/entries/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "name" should be "Project 1"
# create content entry
Scenario: Creating new content entry as an Admin
Given I have an "admin" API token
When I do an API GET request to content_types/projects/entries.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do an API POST to content_types/projects/entries.json with:
"""
{
"content_entry": {
"name": "Project 3",
"description": "The third..."
}
}
"""
When I do an API GET request to content_types/projects/entries.json
Then the JSON response should be an array
And the JSON response should have 3 entries
And the JSON should have the following:
| 2/name | "Project 3" |
| 2/description | "The third..." |
Scenario: Creating new content entry as a Designer
Given I have a "designer" API token
When I do an API GET request to content_types/projects/entries.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do an API POST to content_types/projects/entries.json with:
"""
{
"content_entry": {
"name": "Project 3",
"description": "The third..."
}
}
"""
When I do an API GET request to content_types/projects/entries.json
Then the JSON response should be an array
And the JSON response should have 3 entries
And the JSON should have the following:
| 2/name | "Project 3" |
| 2/description | "The third..." |
Scenario: Creating new content entry as an Author
Given I have an "author" API token
When I do an API GET request to content_types/projects/entries.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do an API POST to content_types/projects/entries.json with:
"""
{
"content_entry": {
"name": "Project 3",
"description": "The third..."
}
}
"""
When I do an API GET request to content_types/projects/entries.json
Then the JSON response should be an array
And the JSON response should have 3 entries
And the JSON should have the following:
| 2/name | "Project 3" |
| 2/description | "The third..." |
# update content entry
Scenario: Updating content entry as an Admin
Given I have an "admin" API token
When I do an API PUT to content_types/projects/entries/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"content_entry": {
"description": "The awesomest project ever!"
}
}
"""
When I do an API GET request to content_types/projects/entries/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "name" should be "Project 1"
And the JSON response at "description" should be "The awesomest project ever!"
Scenario: Updating content entry as a Designer
Given I have a "designer" API token
When I do an API PUT to content_types/projects/entries/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"content_entry": {
"description": "The awesomest project ever!"
}
}
"""
When I do an API GET request to content_types/projects/entries/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "name" should be "Project 1"
And the JSON response at "description" should be "The awesomest project ever!"
Scenario: Updating content entry as an Author
Given I have a "author" API token
When I do an API PUT to content_types/projects/entries/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"content_entry": {
"description": "The awesomest project ever!"
}
}
"""
When I do an API GET request to content_types/projects/entries/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "name" should be "Project 1"
And the JSON response at "description" should be "The awesomest project ever!"
# destroy content entry
Scenario: Destroying content entry as an Admin
Given I have an "admin" API token
When I do an API GET request to content_types/projects/entries.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do an API DELETE to content_types/projects/entries/4f832c2cb0d86d3f42fffffe.json
When I do an API GET request to content_types/projects/entries.json
Then the JSON response should be an array
And the JSON response should have 1 entry
Scenario: Destroying content entry as a Designer
Given I have a "designer" API token
When I do an API GET request to content_types/projects/entries.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do an API DELETE to content_types/projects/entries/4f832c2cb0d86d3f42fffffe.json
When I do an API GET request to content_types/projects/entries.json
Then the JSON response should be an array
And the JSON response should have 1 entry
Scenario: Deleting content entry as an Author
Given I have a "author" API token
When I do an API GET request to content_types/projects/entries.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do an API DELETE to content_types/projects/entries/4f832c2cb0d86d3f42fffffe.json
When I do an API GET request to content_types/projects/entries.json
Then the JSON response should be an array
And the JSON response should have 1 entry

View File

@ -0,0 +1,237 @@
Feature: Content Types
In order to ensure content types are not tampered with
As an admin, designer or author
I will be restricted based on my role
Background:
Given I have the site: "test site" set up
And I have a custom model named "Projects" with id "4f832c2cb0d86d3f42fffffe" and
| label | type | required |
| Name | string | true |
| Description | text | false |
And I have a designer and an author
Scenario: As an unauthenticated user
Given I am not authenticated
When I do an API GET to content_types.json
Then the JSON response at "error" should be "You need to sign in or sign up before continuing."
# listing content types
Scenario: Accessing content types as an Admin
Given I have an "admin" API token
When I do an API GET request to content_types.json
Then the JSON response should be an array
And the JSON response should have 1 entry
Scenario: Accessing content types as a Designer
Given I have a "designer" API token
When I do an API GET request to content_types.json
Then the JSON response should be an array
And the JSON response should have 1 entry
Scenario: Accessing content types as an Author
Given I have an "author" API token
When I do an API GET request to content_types.json
Then the JSON response should be an array
And the JSON response should have 1 entry
# showing content type
Scenario: Accessing content type as an Admin
Given I have an "admin" API token
When I do an API GET request to content_types/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "name" should be "Projects"
Scenario: Accessing content type as a Designer
Given I have a "designer" API token
When I do an API GET request to content_types/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "name" should be "Projects"
Scenario: Accessing content type as an Author
Given I have an "author" API token
When I do an API GET request to content_types/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "name" should be "Projects"
# create content type
Scenario: Creating new content type as an Admin
Given I have an "admin" API token
When I do an API GET request to content_types.json
Then the JSON response should be an array
And the JSON response should have 1 entry
When I do an API POST to content_types.json with:
"""
{
"content_type": {
"name": "Employees",
"slug": "employees",
"entries_custom_fields": [
{
"label": "Name",
"name": "name",
"type": "string"
},
{
"label": "Position",
"name": "position",
"type": "string"
}
]
}
}
"""
When I do an API GET request to content_types.json
Then the JSON response should be an array
And the JSON response should have 2 entries
And the JSON should have the following:
| 1/name | "Employees" |
| 1/slug | "employees" |
| 1/entries_custom_fields/0/label | "Name" |
| 1/entries_custom_fields/0/name | "name" |
| 1/entries_custom_fields/0/type | "string" |
| 1/entries_custom_fields/1/label | "Position" |
| 1/entries_custom_fields/1/name | "position" |
| 1/entries_custom_fields/1/type | "string" |
Scenario: Creating new content type as a Designer
Given I have a "designer" API token
When I do an API GET request to content_types.json
Then the JSON response should be an array
And the JSON response should have 1 entry
When I do an API POST to content_types.json with:
"""
{
"content_type": {
"name": "Employees",
"slug": "employees",
"entries_custom_fields": [
{
"label": "Name",
"name": "name",
"type": "string"
},
{
"label": "Position",
"name": "position",
"type": "string"
}
]
}
}
"""
When I do an API GET request to content_types.json
Then the JSON response should be an array
And the JSON response should have 2 entries
And the JSON should have the following:
| 1/name | "Employees" |
| 1/slug | "employees" |
| 1/entries_custom_fields/0/label | "Name" |
| 1/entries_custom_fields/0/name | "name" |
| 1/entries_custom_fields/0/type | "string" |
| 1/entries_custom_fields/1/label | "Position" |
| 1/entries_custom_fields/1/name | "position" |
| 1/entries_custom_fields/1/type | "string" |
Scenario: Creating new content type as an Author
Given I have an "author" API token
When I do an API GET request to content_types.json
Then the JSON response should be an array
And the JSON response should have 1 entry
When I do an API POST to content_types.json with:
"""
{
"content_type": {
"name": "Employees",
"slug": "employees",
"entries_custom_fields": [
{
"label": "Name",
"name": "name",
"type": "string"
},
{
"label": "Position",
"name": "position",
"type": "string"
}
]
}
}
"""
Then an access denied error should occur
# update content type
Scenario: Updating content type as an Admin
Given I have an "admin" API token
When I do an API PUT to content_types/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"content_type": {
"name": "Brand new updated name"
}
}
"""
When I do an API GET request to content_types/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "name" should be "Brand new updated name"
Scenario: Updating content type as a Designer
Given I have a "designer" API token
When I do an API PUT to content_types/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"content_type": {
"name": "Brand new updated name"
}
}
"""
When I do an API GET request to content_types/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "name" should be "Brand new updated name"
Scenario: Updating content type as an Author
Given I have a "author" API token
When I do an API PUT to content_types/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"content_type": {
"name": "Brand new updated name"
}
}
"""
Then an access denied error should occur
# destroy content type
Scenario: Destroying content type as an Admin
Given I have an "admin" API token
When I do an API GET request to content_types.json
Then the JSON response should be an array
And the JSON response should have 1 entry
When I do an API DELETE to content_types/4f832c2cb0d86d3f42fffffe.json
When I do an API GET request to content_types.json
Then the JSON response should be an array
And the JSON response should have 0 entries
Scenario: Destroying content type as a Designer
Given I have a "designer" API token
When I do an API GET request to content_types.json
Then the JSON response should be an array
And the JSON response should have 1 entry
When I do an API DELETE to content_types/4f832c2cb0d86d3f42fffffe.json
When I do an API GET request to content_types.json
Then the JSON response should be an array
And the JSON response should have 0 entries
Scenario: Deleting content type as an Author
Given I have a "author" API token
When I do an API GET request to content_types.json
Then the JSON response should be an array
And the JSON response should have 1 entries
When I do an API DELETE to content_types/4f832c2cb0d86d3f42fffffe.json
Then an access denied error should occur

View File

@ -0,0 +1,30 @@
Feature: Current Site
In order to ensure the current site can be viewed by all authenticated users
As an admin, designer or author
I should be able to show the current site
Background:
Given I have the site: "test site" set up
And I have a designer and an author
Scenario: As an unauthenticated user
Given I am not authenticated
When I do an API GET to current_site.json
Then the JSON response at "error" should be "You need to sign in or sign up before continuing."
# showing current site
Scenario: Accessing current site as an Admin
Given I have an "admin" API token
When I do an API GET to current_site.json
Then the JSON response at "name" should be "Locomotive test website"
Scenario: Accessing current site as a Designer
Given I have a "designer" API token
When I do an API GET to current_site.json
Then the JSON response at "name" should be "Locomotive test website"
Scenario: Accessing current site as an Author
Given I have an "author" API token
When I do an API GET to current_site.json
Then the JSON response at "name" should be "Locomotive test website"

View File

@ -0,0 +1,225 @@
Feature: Memberships
In order to ensure memberships are not tampered with
As an admin, designer or author
I will be restricted based on my role
Background:
Given I have the site: "test site" set up with id: "4f832c2cb0d86d3f42fffffb"
And I have accounts:
| email | id |
| new-user@a.com | 4f832c2cb0d86d3f42fffffc |
And I have memberships:
| email | role | id |
| admin@a.com | admin | 4f832c2cb0d86d3f42fffffd |
| designer@a.com | designer | 4f832c2cb0d86d3f42fffffe |
| author@a.com | author | 4f832c2cb0d86d3f42ffffff |
Scenario: As an unauthenticated user
Given I am not authenticated
When I do an API GET to memberships.json
Then the JSON response at "error" should be "You need to sign in or sign up before continuing."
# listing memberships
Scenario: Accessing memberships as an Admin
Given I have an "admin" API token
When I do an API GET request to memberships.json
Then the JSON response should be an array
And the JSON response should have 4 entries
Scenario: Accessing memberships as a Designer
Given I have a "designer" API token
When I do an API GET request to memberships.json
Then the JSON response should be an array
And the JSON response should have 4 entries
Scenario: Accessing memberships as an Author
Given I have an "author" API token
When I do an API GET request to memberships.json
Then an access denied error should occur
# showing membership
Scenario: Accessing membership as an Admin
Given I have an "admin" API token
When I do an API GET request to memberships/4f832c2cb0d86d3f42fffffd.json
Then the JSON response at "email" should be "admin@a.com"
When I do an API GET request to memberships/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "email" should be "designer@a.com"
When I do an API GET request to memberships/4f832c2cb0d86d3f42ffffff.json
Then the JSON response at "email" should be "author@a.com"
Scenario: Accessing membership as a Designer
Given I have a "designer" API token
When I do an API GET request to memberships/4f832c2cb0d86d3f42fffffd.json
Then the JSON response at "email" should be "admin@a.com"
When I do an API GET request to memberships/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "email" should be "designer@a.com"
When I do an API GET request to memberships/4f832c2cb0d86d3f42ffffff.json
Then the JSON response at "email" should be "author@a.com"
Scenario: Accessing membership as an Author
Given I have an "author" API token
When I do an API GET request to memberships/4f832c2cb0d86d3f42fffffe.json
Then an access denied error should occur
# create membership
Scenario: Creating new membership as an Admin
Given I have an "admin" API token
When I do an API POST to memberships.json with:
"""
{
"membership": {
"site_id": "4f832c2cb0d86d3f42fffffb",
"account_id": "4f832c2cb0d86d3f42fffffc"
}
}
"""
When I do an API GET request to memberships.json
Then the JSON response should be an array
And the JSON response should have 5 entries
Scenario: Creating new membership as a Designer
Given I have a "designer" API token
When I do an API POST to memberships.json with:
"""
{
"membership": {
"site_id": "4f832c2cb0d86d3f42fffffb",
"account_id": "4f832c2cb0d86d3f42fffffc"
}
}
"""
When I do an API GET request to memberships.json
Then the JSON response should be an array
And the JSON response should have 5 entries
Scenario: Creating new membership as an Author
Given I have an "author" API token
When I do an API POST to memberships.json with:
"""
{
"membership": {
"site_id": "4f832c2cb0d86d3f42fffffb",
"account_id": "4f832c2cb0d86d3f42fffffc"
}
}
"""
Then an access denied error should occur
Scenario: Created membership should always be Author
Given I have an "admin" API token
When I do an API POST to memberships.json with:
"""
{
"membership": {
"site_id": "4f832c2cb0d86d3f42fffffb",
"account_id": "4f832c2cb0d86d3f42fffffc",
"role": "admin"
}
}
"""
When I do an API GET request to memberships.json
Then the JSON response should be an array
And the JSON response should have 5 entries
And the JSON at "4/role" should be "author"
# update membership
Scenario: Updating membership as an Admin
Given I have an "admin" API token
When I do an API PUT to memberships/4f832c2cb0d86d3f42ffffff.json with:
"""
{
"membership": {
"role": "admin"
}
}
"""
When I do an API GET request to memberships/4f832c2cb0d86d3f42ffffff.json
Then the JSON response at "role" should be "admin"
Scenario: Updating membership as a Designer
Given I have a "designer" API token
When I do an API PUT to memberships/4f832c2cb0d86d3f42ffffff.json with:
"""
{
"membership": {
"role": "admin"
}
}
"""
When I do an API GET request to memberships/4f832c2cb0d86d3f42ffffff.json
Then the JSON response at "role" should be "author"
When I do an API PUT to memberships/4f832c2cb0d86d3f42ffffff.json with:
"""
{
"membership": {
"role": "designer"
}
}
"""
When I do an API GET request to memberships/4f832c2cb0d86d3f42ffffff.json
Then the JSON response at "role" should be "designer"
Scenario: Updating membership as an Author
Given I have a "author" API token
When I do an API PUT to memberships/4f832c2cb0d86d3f42ffffff.json with:
"""
{
"membership": {
"role": "admin"
}
}
"""
Then an access denied error should occur
When I do an API PUT to memberships/4f832c2cb0d86d3f42ffffff.json with:
"""
{
"membership": {
"role": "designer"
}
}
"""
Then an access denied error should occur
When I do an API PUT to memberships/4f832c2cb0d86d3f42ffffff.json with:
"""
{
"membership": {
"role": "author"
}
}
"""
Then an access denied error should occur
# destroy membership
Scenario: Destroying membership as an Admin
Given I have an "admin" API token
When I do an API GET request to memberships.json
Then the JSON response should be an array
And the JSON response should have 4 entries
When I do an API DELETE to memberships/4f832c2cb0d86d3f42ffffff.json
When I do an API GET request to memberships.json
Then the JSON response should be an array
And the JSON response should have 3 entries
Scenario: Destroying membership as a Designer
Given I have a "designer" API token
When I do an API GET request to memberships.json
Then the JSON response should be an array
And the JSON response should have 4 entries
When I do an API DELETE to memberships/4f832c2cb0d86d3f42ffffff.json
When I do an API GET request to memberships.json
Then the JSON response should be an array
And the JSON response should have 3 entries
When I do an API DELETE to memberships/4f832c2cb0d86d3f42fffffe.json
Then an access denied error should occur
When I do an API DELETE to memberships/4f832c2cb0d86d3f42fffffd.json
Then an access denied error should occur
Scenario: Deleting membership as an Author
Given I have a "author" API token
When I do an API DELETE to memberships/4f832c2cb0d86d3f42fffffe.json
Then an access denied error should occur

View File

@ -0,0 +1,187 @@
Feature: Pages
In order to ensure pages are not tampered with
As an admin, designer or author
I will be restricted based on my role
Background:
Given I have the site: "test site" set up
And I have a custom model named "Projects" with
| label | type | required |
| Name | string | true |
| Description | text | false |
And I have a designer and an author
And a page named "hello-world" with id "4f832c2cb0d86d3f42fffffe"
And a page named "goodbye-world" with id "4f832c2cb0d86d3f42ffffff"
Scenario: As an unauthenticated user
Given I am not authenticated
When I do an API GET to pages.json
Then the JSON response at "error" should be "You need to sign in or sign up before continuing."
# listing pages
Scenario: Accessing pages as an Admin
Given I have an "admin" API token
When I do an API GET request to pages.json
Then the JSON response should be an array
And the JSON response should have 4 entries
Scenario: Accessing pages as a Designer
Given I have a "designer" API token
When I do an API GET request to pages.json
Then the JSON response should be an array
And the JSON response should have 4 entries
Scenario: Accessing pages as an Author
Given I have an "author" API token
When I do an API GET request to pages.json
Then the JSON response should be an array
And the JSON response should have 4 entries
# showing page
Scenario: Accessing page as an Admin
Given I have an "admin" API token
When I do an API GET request to pages/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "slug" should be "hello-world"
Scenario: Accessing page as a Designer
Given I have a "designer" API token
When I do an API GET request to pages/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "slug" should be "hello-world"
Scenario: Accessing page as an Author
Given I have an "author" API token
When I do an API GET request to pages/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "slug" should be "hello-world"
# create page
Scenario: Creating new page as an Admin
Given I have an "admin" API token
When I do an API GET request to pages.json
Then the JSON response should be an array
And the JSON response should have 4 entries
When I do an API POST to pages.json with:
"""
{
"page": {
"title": "New Page",
"slug": "new-page",
"parent_id": "4f832c2cb0d86d3f42fffffe"
}
}
"""
When I do an API GET request to pages.json
Then the JSON response should be an array
And the JSON response should have 5 entries
Scenario: Creating new page as a Designer
Given I have a "designer" API token
When I do an API GET request to pages.json
Then the JSON response should be an array
And the JSON response should have 4 entries
When I do an API POST to pages.json with:
"""
{
"page": {
"title": "New Page",
"slug": "new-page",
"parent_id": "4f832c2cb0d86d3f42fffffe"
}
}
"""
When I do an API GET request to pages.json
Then the JSON response should be an array
And the JSON response should have 5 entries
Scenario: Creating new page as an Author
Given I have an "author" API token
When I do an API POST to pages.json with:
"""
{
"page": {
"title": "New Page",
"slug": "new-page",
"parent_id": "4f832c2cb0d86d3f42fffffe"
}
}
"""
Then an access denied error should occur
# update page
Scenario: Updating page as an Admin
Given I have an "admin" API token
When I do an API PUT to pages/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"page": {
"title": "Brand new updated title"
}
}
"""
When I do an API GET request to pages/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "title" should be "Brand new updated title"
Scenario: Updating page as a Designer
Given I have a "designer" API token
When I do an API PUT to pages/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"page": {
"title": "Brand new updated title"
}
}
"""
When I do an API GET request to pages/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "title" should be "Brand new updated title"
Scenario: Updating page as an Author
Given I have a "author" API token
When I do an API PUT to pages/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"page": {
"title": "Brand new updated title"
}
}
"""
When I do an API GET request to pages/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "title" should be "Brand new updated title"
# destroy page
Scenario: Destroying page as an Admin
Given I have an "admin" API token
When I do an API GET request to pages.json
Then the JSON response should be an array
And the JSON response should have 4 entries
When I do an API DELETE to pages/4f832c2cb0d86d3f42fffffe.json
When I do an API GET request to pages.json
Then the JSON response should be an array
And the JSON response should have 3 entries
Scenario: Destroying page as a Designer
Given I have a "designer" API token
When I do an API GET request to pages.json
Then the JSON response should be an array
And the JSON response should have 4 entries
When I do an API DELETE to pages/4f832c2cb0d86d3f42fffffe.json
When I do an API GET request to pages.json
Then the JSON response should be an array
And the JSON response should have 3 entries
Scenario: Deleting page as an Author
Given I have a "author" API token
When I do an API GET request to pages.json
Then the JSON response should be an array
And the JSON response should have 4 entries
When I do an API DELETE to pages/4f832c2cb0d86d3f42fffffe.json
Then an access denied error should occur

View File

@ -0,0 +1,206 @@
Feature: Sites
In order to ensure sites are not tampered with
As an admin, designer or author
I will be restricted based on my role
Background:
Given I have the site: "test site" set up with id: "4f832c2cb0d86d3f42fffffe"
And I have the site: "another site" set up with id: "4f832c2cb0d86d3f42ffffff"
And I have a designer and an author
Scenario: As an unauthenticated user
Given I am not authenticated
When I do an API GET to sites.json
Then the JSON response at "error" should be "You need to sign in or sign up before continuing."
# listing sites
Scenario: Accessing sites as an Admin
Given I have an "admin" API token
When I do an API GET request to sites.json
Then the JSON response should be an array
And the JSON response should have 2 entries
Scenario: Accessing sites as a Designer
Given I have a "designer" API token
When I do an API GET request to sites.json
Then an access denied error should occur
Scenario: Accessing sites as an Author
Given I have an "author" API token
When I do an API GET request to sites.json
Then an access denied error should occur
# showing site
Scenario: Accessing site as an Admin
Given I have an "admin" API token
When I do an API GET request to sites/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "name" should be "Locomotive test website"
Scenario: Accessing my site as a Designer
Given I have a "designer" API token
When I do an API GET request to sites/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "name" should be "Locomotive test website"
Scenario: Accessing other site as a Designer
Given I have a "designer" API token
When I do an API GET request to sites/4f832c2cb0d86d3f42ffffff.json
Then an access denied error should occur
Scenario: Accessing my site as an Author
Given I have an "author" API token
When I do an API GET request to sites/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "name" should be "Locomotive test website"
Scenario: Accessing other site as an Author
Given I have an "author" API token
When I do an API GET request to sites/4f832c2cb0d86d3f42ffffff.json
Then an access denied error should occur
# create site
Scenario: Creating new site as an Admin
Given I have an "admin" API token
When I do an API GET request to sites.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do an API POST to sites.json with:
"""
{
"site": {
"name": "New site",
"subdomain": "new-site"
}
}
"""
When I do an API GET request to sites.json
Then the JSON response should be an array
And the JSON response should have 3 entries
Scenario: Creating new site as a Designer
Given I have a "designer" API token
When I do an API POST to sites.json with:
"""
{
"site": {
"name": "New site",
"subdomain": "new-site"
}
}
"""
Then an access denied error should occur
Scenario: Creating new site as an Author
Given I have an "author" API token
When I do an API POST to sites.json with:
"""
{
"site": {
"name": "New site",
"subdomain": "new-site"
}
}
"""
Then an access denied error should occur
# update site
Scenario: Updating site as an Admin
Given I have an "admin" API token
When I do an API PUT to sites/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"site": {
"name": "Brand new updated name"
}
}
"""
When I do an API GET request to sites/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "name" should be "Brand new updated name"
Scenario: Updating my site as a Designer
Given I have a "designer" API token
When I do an API PUT to sites/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"site": {
"name": "Brand new updated name"
}
}
"""
When I do an API GET request to sites/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "name" should be "Brand new updated name"
Scenario: Updating other site as a Designer
Given I have a "designer" API token
When I do an API PUT to sites/4f832c2cb0d86d3f42ffffff.json with:
"""
{
"site": {
"name": "Brand new updated name"
}
}
"""
Then an access denied error should occur
Scenario: Updating my site as an Author
Given I have a "author" API token
When I do an API PUT to sites/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"site": {
"name": "Brand new updated name"
}
}
"""
When I do an API GET request to sites/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "name" should be "Brand new updated name"
Scenario: Updating other site as an Author
Given I have a "author" API token
When I do an API PUT to sites/4f832c2cb0d86d3f42ffffff.json with:
"""
{
"site": {
"name": "Brand new updated name"
}
}
"""
Then an access denied error should occur
# destroy site
Scenario: Destroying site as an Admin
Given I have an "admin" API token
When I do an API GET request to sites.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do an API DELETE to sites/4f832c2cb0d86d3f42fffffe.json
When I do an API GET request to sites.json
Then the JSON response should be an array
And the JSON response should have 1 entries
Scenario: Destroying my site as a Designer
Given I have a "designer" API token
When I do an API DELETE to sites/4f832c2cb0d86d3f42fffffe.json
When I do an API GET request to sites/4f832c2cb0d86d3f42fffffe.json
Then it should not exist
Scenario: Deleting other site as a Designer
Given I have a "designer" API token
When I do an API DELETE to sites/4f832c2cb0d86d3f42ffffff.json
Then an access denied error should occur
Scenario: Deleting my site as an Author
Given I have a "author" API token
When I do an API DELETE to sites/4f832c2cb0d86d3f42fffffe.json
Then an access denied error should occur
Scenario: Deleting other site as an Author
Given I have a "author" API token
When I do an API DELETE to sites/4f832c2cb0d86d3f42ffffff.json
Then an access denied error should occur

View File

@ -0,0 +1,179 @@
Feature: Snippets
In order to ensure snippets are not tampered with
As an admin, designer or author
I will be restricted based on my role
Background:
Given I have the site: "test site" set up
And a snippet named "My Snippet" with id "4f832c2cb0d86d3f42fffffe" and template:
"""
My Snippet
"""
And I have a designer and an author
Scenario: As an unauthenticated user
Given I am not authenticated
When I do an API GET to snippets.json
Then the JSON response at "error" should be "You need to sign in or sign up before continuing."
# listing content types
Scenario: Accessing snippets as an Admin
Given I have an "admin" API token
When I do an API GET request to snippets.json
Then the JSON response should be an array
And the JSON response should have 1 entry
Scenario: Accessing snippets as a Designer
Given I have a "designer" API token
When I do an API GET request to snippets.json
Then the JSON response should be an array
And the JSON response should have 1 entry
Scenario: Accessing snippets as an Author
Given I have an "author" API token
When I do an API GET request to snippets.json
Then an access denied error should occur
# showing snippet
Scenario: Accessing snippet as an Admin
Given I have an "admin" API token
When I do an API GET request to snippets/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "name" should be "My Snippet"
Scenario: Accessing snippet as a Designer
Given I have a "designer" API token
When I do an API GET request to snippets/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "id" should be "4f832c2cb0d86d3f42fffffe"
And the JSON response at "name" should be "My Snippet"
Scenario: Accessing snippet as an Author
Given I have an "author" API token
When I do an API GET request to snippets/4f832c2cb0d86d3f42fffffe.json
Then an access denied error should occur
# create snippet
Scenario: Creating new snippet as an Admin
Given I have an "admin" API token
When I do an API GET request to snippets.json
Then the JSON response should be an array
And the JSON response should have 1 entry
When I do an API POST to snippets.json with:
"""
{
"snippet": {
"name": "Another snippet",
"template": "<h1>Another Snippet!</h1>"
}
}
"""
When I do an API GET request to snippets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
And the JSON should have the following:
| 1/name | "Another Snippet" |
| 1/template | "<h1>Another Snippet!</h1>" |
Scenario: Creating new snippet as a Designer
Given I have a "designer" API token
When I do an API GET request to snippets.json
Then the JSON response should be an array
And the JSON response should have 1 entry
When I do an API POST to snippets.json with:
"""
{
"snippet": {
"name": "Another snippet",
"template": "<h1>Another Snippet!</h1>"
}
}
"""
When I do an API GET request to snippets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
And the JSON should have the following:
| 1/name | "Another Snippet" |
| 1/template | "<h1>Another Snippet!</h1>" |
Scenario: Creating new snippet as an Author
Given I have an "author" API token
When I do an API POST to snippets.json with:
"""
{
"snippet": {
"name": "Another snippet",
"template": "<h1>Another Snippet!</h1>"
}
}
"""
Then an access denied error should occur
# update snippet
Scenario: Updating snippet as an Admin
Given I have an "admin" API token
When I do an API PUT to snippets/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"snippet": {
"name": "Brand new updated name"
}
}
"""
When I do an API GET request to snippets/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "name" should be "Brand new updated name"
Scenario: Updating snippet as a Designer
Given I have a "designer" API token
When I do an API PUT to snippets/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"snippet": {
"name": "Brand new updated name"
}
}
"""
When I do an API GET request to snippets/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "name" should be "Brand new updated name"
Scenario: Updating snippet as an Author
Given I have a "author" API token
When I do an API PUT to snippets/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"snippet": {
"name": "Brand new updated name"
}
}
"""
Then an access denied error should occur
# destroy snippet
Scenario: Destroying snippet as an Admin
Given I have an "admin" API token
When I do an API GET request to snippets.json
Then the JSON response should be an array
And the JSON response should have 1 entry
When I do an API DELETE to snippets/4f832c2cb0d86d3f42fffffe.json
When I do an API GET request to snippets.json
Then the JSON response should be an array
And the JSON response should have 0 entries
Scenario: Destroying snippet as a Designer
Given I have a "designer" API token
When I do an API GET request to snippets.json
Then the JSON response should be an array
And the JSON response should have 1 entry
When I do an API DELETE to snippets/4f832c2cb0d86d3f42fffffe.json
When I do an API GET request to snippets.json
Then the JSON response should be an array
And the JSON response should have 0 entries
Scenario: Deleting snippet as an Author
Given I have a "author" API token
When I do an API DELETE to snippets/4f832c2cb0d86d3f42fffffe.json
Then an access denied error should occur

View File

@ -0,0 +1,185 @@
Feature: Theme Assets
In order to ensure theme assets are not tampered with
As an admin, designer or author
I will be restricted based on my role
Background:
Given I have the site: "test site" set up
And a javascript asset named "my_javascript.js" with id "4f832c2cb0d86d3f42fffffe"
And a stylesheet asset named "my_stylesheet.css" with id "4f832c2cb0d86d3f42ffffff"
Scenario: As an unauthenticated user
Given I am not authenticated
When I do an API GET to theme_assets.json
Then the JSON response at "error" should be "You need to sign in or sign up before continuing."
# listing theme assets
Scenario: Accessing theme assets as an Admin
Given I have an "admin" API token
When I do an API GET request to theme_assets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
Scenario: Accessing theme assets as a Designer
Given I have a "designer" API token
When I do an API GET request to theme_assets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
Scenario: Accessing theme assets as an Author
Given I have an "author" API token
When I do an API GET request to theme_assets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
# showing theme asset
Scenario: Accessing theme asset as an Admin
Given I have an "admin" API token
When I do an API GET request to theme_assets/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "local_path" should be "my_javascript.js"
Scenario: Accessing theme asset as a Designer
Given I have a "designer" API token
When I do an API GET request to theme_assets/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "local_path" should be "my_javascript.js"
Scenario: Accessing theme asset as an Author
Given I have an "author" API token
When I do an API GET request to theme_assets/4f832c2cb0d86d3f42fffffe.json
Then the JSON response at "local_path" should be "my_javascript.js"
# create theme asset
Scenario: Creating new theme asset as an Admin
Given I have an "admin" API token
When I do an API GET request to theme_assets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do an API POST to theme_assets.json with:
"""
{
"theme_asset": {
"plain_text_name": "new-javascript.js",
"plain_text": "function doNothing() {}",
"plain_text_type": "javascript",
"performing_plain_text": "true"
}
}
"""
When I do an API GET request to theme_assets.json
Then the JSON response should be an array
And the JSON response should have 3 entries
And the JSON should have the following:
| 2/local_path | "new-javascript.js" |
| 2/content_type | "javascript" |
Scenario: Creating new theme asset as a Designer
Given I have a "designer" API token
When I do an API GET request to theme_assets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do an API POST to theme_assets.json with:
"""
{
"theme_asset": {
"plain_text_name": "new-javascript.js",
"plain_text": "function doNothing() {}",
"plain_text_type": "javascript",
"performing_plain_text": "true"
}
}
"""
When I do an API GET request to theme_assets.json
Then the JSON response should be an array
And the JSON response should have 3 entries
And the JSON should have the following:
| 2/local_path | "new-javascript.js" |
| 2/content_type | "javascript" |
Scenario: Creating new theme asset as an Author
Given I have an "author" API token
When I do an API POST to theme_assets.json with:
"""
{
"theme_asset": {
"plain_text_name": "new-javascript.js",
"plain_text": "function doNothing() {}",
"plain_text_type": "javascript",
"performing_plain_text": "true"
}
}
"""
Then an access denied error should occur
# update theme asset
Scenario: Updating theme asset as an Admin
Given I have an "admin" API token
When I do an API PUT to theme_assets/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"theme_asset": {
"plain_text_name": "newer-javascript.js"
}
}
"""
When I do an API GET request to theme_assets/4f832c2cb0d86d3f42fffffe.json
Then the JSON response should have the following:
| local_path | "newer-javascript.js" |
Scenario: Updating theme asset as a Designer
Given I have a "designer" API token
When I do an API PUT to theme_assets/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"theme_asset": {
"plain_text_name": "newer-javascript.js"
}
}
"""
When I do an API GET request to theme_assets/4f832c2cb0d86d3f42fffffe.json
Then the JSON response should have the following:
| local_path | "newer-javascript.js" |
Scenario: Updating theme asset as an Author
Given I have a "author" API token
When I do an API PUT to theme_assets/4f832c2cb0d86d3f42fffffe.json with:
"""
{
"theme_asset": {
"plain_text_name": "newer-javascript.js"
}
}
"""
When I do an API GET request to theme_assets/4f832c2cb0d86d3f42fffffe.json
Then the JSON response should have the following:
| local_path | "newer-javascript.js" |
# destroy theme asset
Scenario: Destroying theme asset as an Admin
Given I have an "admin" API token
When I do an API GET request to theme_assets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do an API DELETE to theme_assets/4f832c2cb0d86d3f42fffffe.json
When I do an API GET request to theme_assets.json
Then the JSON response should be an array
And the JSON response should have 1 entries
Scenario: Destroying theme asset as a Designer
Given I have a "designer" API token
When I do an API GET request to theme_assets.json
Then the JSON response should be an array
And the JSON response should have 2 entries
When I do an API DELETE to theme_assets/4f832c2cb0d86d3f42fffffe.json
When I do an API GET request to theme_assets.json
Then the JSON response should be an array
And the JSON response should have 1 entries
Scenario: Deleting theme asset as an Author
Given I have a "author" API token
When I do an API DELETE to theme_assets/4f832c2cb0d86d3f42fffffe.json
Then an access denied error should occur

View File

@ -1,3 +1,26 @@
def api_base_url
"http://#{Locomotive::Site.first.domains.first}/locomotive/api/"
end
def do_api_request(type, url, param_string_or_hash = nil)
begin
if param_string_or_hash
if param_string_or_hash.is_a? Hash
params = param_string_or_hash
else
params = JSON.parse(param_string_or_hash)
end
else
params = {}
end
@json_response = do_request(type, api_base_url, url,
params.merge({ 'CONTENT_TYPE' => 'application/json' }))
rescue CanCan::AccessDenied, Mongoid::Errors::DocumentNotFound
@error = $!
end
end
def last_json
@json_response.try(:body) || page.source
end
@ -11,13 +34,16 @@ Given /^I have an? "([^"]*)" API token$/ do |role|
'password' => 'easyone'
}
response = post("http://#{@site.domains.first}/locomotive/api/tokens.json", login_params.to_json, { 'CONTENT_TYPE' => 'application/json' })
response = do_request('POST', api_base_url, 'tokens.json',
login_params.merge({ 'CONTENT_TYPE' => 'application/json' }))
if response.status == 200
@auth_token = JSON.parse(response.body)['token']
else
raise JSON.parse(response.body)['message']
end
add_default_params(:auth_token => @auth_token)
end
Given /^I do not have an API token$/ do
@ -35,4 +61,36 @@ end
When /^I post to "([^"]*)" with:$/ do |path, json_string|
@json_response = post("http://#{@site.domains.first}#{path}", json_string, { 'CONTENT_TYPE' => 'application/json' })
end
end
When /^I do an API (\w+) (?:request )?to ([\w.\/]+)$/ do |request_type, url|
do_api_request(request_type, url)
end
When /^I do an API (\w+) (?:request )?to ([\w.\/]+) with:$/ do |request_type, url, param_string|
do_api_request(request_type, url, param_string)
end
Then /^an access denied error should occur$/ do
@error.should_not be_nil
@error.is_a?(CanCan::AccessDenied).should be_true
end
Then /^it should not exist$/ do
@error.should_not be_nil
@error.is_a?(Mongoid::Errors::DocumentNotFound).should be_true
end
When /^I do a multipart API (\w+) (?:request )?to ([\w.\/]+) with base key "([^"]*)" and:$/ \
do |request_type, url, base_key, table|
params = {}
params = table.rows_hash
params.each do |key, filename|
params[key] = Rack::Test::UploadedFile.new(Rails.root.join('..', 'fixtures', filename))
end
do_api_request(request_type, url, { base_key => params })
end
Then /^I print the json response$/ do
puts %{JSON: "#{last_json}"}
end

View File

@ -0,0 +1,12 @@
Given /^I have the following content assets:$/ do |table|
site = Locomotive::Site.first
table.hashes.each do |asset_hash|
asset_hash['site'] = site
asset_hash['source'] = FixturedAsset.open(asset_hash['file'])
asset_hash.delete('file')
asset = FactoryGirl.build(:asset, asset_hash)
asset.save.should be_true
end
end

View File

@ -1,6 +1,9 @@
Given %r{^I have a custom model named "([^"]*)" with$} do |name, fields|
def build_content_type(name)
site = Locomotive::Site.first
content_type = FactoryGirl.build(:content_type, :site => site, :name => name, :order_by => '_position')
FactoryGirl.build(:content_type, :site => site, :name => name, :order_by => '_position')
end
def set_custom_fields_from_table(content_type, fields)
fields.hashes.each do |field|
# found a belongs_to association
if field['type'] == 'belongs_to'
@ -12,6 +15,19 @@ Given %r{^I have a custom model named "([^"]*)" with$} do |name, fields|
content_type.entries_custom_fields.build field
end
end
Given %r{^I have a custom model named "([^"]*)" with id "([^"]*)" and$} do |name, id, fields|
content_type = build_content_type(name)
content_type.id = BSON::ObjectId(id)
set_custom_fields_from_table(content_type, fields)
content_type.valid?
content_type.save.should be_true
end
Given %r{^I have a custom model named "([^"]*)" with$} do |name, fields|
content_type = build_content_type(name)
set_custom_fields_from_table(content_type, fields)
content_type.valid?
content_type.save.should be_true
end

View File

@ -0,0 +1,19 @@
Given /^I have accounts:$/ do |accounts_table|
accounts_table.hashes.each do |account_hash|
FactoryGirl.create(:account, account_hash)
end
end
Given /^I have memberships:$/ do |members_table|
members_table.hashes.each do |member_hash|
email = member_hash[:email]
account = Locomotive::Account.where(:email => email).first \
|| FactoryGirl.create(:account, :email => email)
member_hash.delete(:email)
member_hash.merge!({ :account => account, :site => @site })
FactoryGirl.create(:membership, member_hash)
end
end

View File

@ -2,9 +2,16 @@
# helps create a simple content page (parent: "index") with a slug, contents, and template
def create_content_page(page_slug, page_contents, template = nil)
@home = @site.pages.where(:slug => "index").first || FactoryGirl.create(:page)
page = @site.pages.create(:slug => page_slug, :body => page_contents, :parent => @home, :title => "some title", :published => true, :raw_template => template)
page = new_content_page(page_slug, page_contents, template)
page.should be_valid
page.save!
page
end
# build page without saving
def new_content_page(page_slug, page_contents, template = nil)
@home = @site.pages.where(:slug => "index").first || FactoryGirl.create(:page)
page = @site.pages.new(:slug => page_slug, :body => page_contents, :parent => @home, :title => "some title", :published => true, :raw_template => template)
page
end
@ -17,6 +24,12 @@ Given /^a page named "([^"]*)" with the template:$/ do |page_slug, template|
@page = create_content_page(page_slug, '', template)
end
Given /^a page named "([^"]*)" with id "([^"]*)"$/ do |page_slug, id|
@page = new_content_page(page_slug, '')
@page.id = BSON::ObjectId(id)
@page.save!
end
# change the title
When /^I change the page title to "([^"]*)"$/ do |page_title|
page.evaluate_script "window.prompt = function() { return '#{page_title}'; }"

View File

@ -1,9 +1,13 @@
### Snippets
# helps create a simple snippet with a slug and template
def new_snippet(name, template = nil)
@site.snippets.new(:name => name, :template => template)
end
def create_snippet(name, template = nil)
snippet = @site.snippets.create(:name => name, :template => template)
snippet.should be_valid
snippet = new_snippet(name, template)
snippet.save!
snippet
end
@ -13,6 +17,12 @@ Given /^a snippet named "([^"]*)" with the template:$/ do |name, template|
@snippet = create_snippet(name, template)
end
Given /^a snippet named "([^"]*)" with id "([^"]*)" and template:$/ do |name, id, template|
@snippet = new_snippet(name, template)
@snippet.id = BSON::ObjectId(id)
@snippet.save!
end
When /^I change the snippet template to "([^"]*)"$/ do |code|
page.evaluate_script "window.application_view.view.editor.setValue('#{code}')"
end

View File

@ -1,15 +1,18 @@
### Theme assets
# helps create a theme asset
def create_plain_text_asset(name, type)
asset = FactoryGirl.build(:theme_asset, {
def new_plain_text_asset(name, type)
FactoryGirl.build(:theme_asset, {
:site => @site,
:plain_text_name => name,
:plain_text => 'Lorem ipsum',
:plain_text_type => type,
:performing_plain_text => true
})
end
def create_plain_text_asset(name, type)
asset = new_plain_text_asset(name, type)
asset.save!
end
@ -19,10 +22,22 @@ Given /^a javascript asset named "([^"]*)"$/ do |name|
@asset = create_plain_text_asset(name, 'javascript')
end
Given /^a javascript asset named "([^"]*)" with id "([^"]*)"$/ do |name, id|
@asset = new_plain_text_asset(name, 'javascript')
@asset.id = BSON::ObjectId(id)
@asset.save!
end
Given /^a stylesheet asset named "([^"]*)"$/ do |name|
@asset = create_plain_text_asset(name, 'stylesheet')
end
Given /^a stylesheet asset named "([^"]*)" with id "([^"]*)"$/ do |name, id|
@asset = new_plain_text_asset(name, 'stylesheet')
@asset.id = BSON::ObjectId(id)
@asset.save!
end
Given /^I have an image theme asset named "([^"]*)"$/ do |name|
@asset = FactoryGirl.create(:theme_asset, :site => @site, :source => File.open(Rails.root.join('..', 'fixtures', 'assets', '5k.png')))
@asset.source_filename = name

22
features/support/http.rb Normal file
View File

@ -0,0 +1,22 @@
module HTTPHelpers
attr_accessor :default_params
def add_default_params(params)
default_params.merge!(params)
end
def do_request(type, base_url, url, params)
request_method = type.downcase.to_sym
send(request_method, "#{base_url}/#{url}", default_params.merge(params))
end
protected
def default_params
@default_params ||= {}
end
end
World(HTTPHelpers)

BIN
spec/fixtures/assets/5k_2.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB