Skip to content
Closed
Show file tree
Hide file tree
Changes from 47 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
ee721cd
add phpstorm configuration to gitignore
adou600 Nov 30, 2012
13e6531
WIP: creation of pages from the menu, not working yet
adou600 Dec 4, 2012
12d3d3a
WIP remove unnecessary composer require
adou600 Dec 4, 2012
56fe68f
Merge branch 'master' into content-creation
adou600 Dec 11, 2012
c600811
WIP creation of news with CreateJS
adou600 Dec 13, 2012
1b08fa4
fix the tests: there is a new entry in the menu
adou600 Dec 13, 2012
1d6213c
WIP test for the news system
adou600 Dec 13, 2012
10fc0c0
dirty hack to hide duplicate +Add buttons on content creation
adou600 Dec 13, 2012
19caf1b
use the configuration to define plain text types instead of custom sc…
adou600 Dec 14, 2012
76451db
update dependencies
adou600 Dec 14, 2012
fead397
finalize the RSS feed for the news list
adou600 Dec 14, 2012
5d581db
get the created entity subject in JS
adou600 Dec 14, 2012
5cea08a
merge master and update dependencies
adou600 Dec 18, 2012
a7692c4
temporary CSS hack to hide multiple add buttons
adou600 Dec 18, 2012
b71ebde
WIP functional backend route creation
adou600 Dec 21, 2012
f8ed1f5
move CmfRoute to the CreateBundle
adou600 Dec 28, 2012
e472a33
list of rdf types for which to create routes
adou600 Dec 28, 2012
572b512
update dependencies to add saucelabs testing, with corresponding smal…
adou600 Jan 8, 2013
deba370
merge master
adou600 Jan 8, 2013
75e82dc
WIP - first experiments with Saucelabs frontend testing
adou600 Jan 8, 2013
231bfb8
fix test refactoring to work with Sauce base class
adou600 Jan 9, 2013
c2bc237
load fixtures for Sauce test cases
adou600 Jan 9, 2013
c556fa9
do not run the sauce tests by default
adou600 Jan 9, 2013
048afab
load fixtures for sauce tests through a FixtureLoader class
adou600 Jan 9, 2013
95af512
WIP news creation with saucelabs
adou600 Jan 9, 2013
aaa1634
news creation test finalization with saucelabs
adou600 Jan 10, 2013
43cdb1d
write today when creating a news instead of the first creation date
adou600 Jan 10, 2013
47c0573
saucelabs tests refactoring and stabilization
adou600 Jan 10, 2013
5b6b03b
documentation how to setup the saucelabs tests
adou600 Jan 10, 2013
b5f763d
documentation formatting
adou600 Jan 10, 2013
c4a5295
various formatting fixes
adou600 Jan 10, 2013
001cfd5
update dependencies and sauce tests after fix in phpunit-selenium
adou600 Jan 17, 2013
941288a
merge master
adou600 Jan 17, 2013
844160e
remove css hack for multiple add buttons
adou600 Jan 17, 2013
7f0155f
composer update with --prefer-source on
adou600 Jan 17, 2013
5ce5657
new test case about simultaneous content creation and update
adou600 Jan 17, 2013
9437599
config changes to handle configurable rdfmapper
adou600 Jan 18, 2013
0db69bf
config update after createphp RdfTypeFactory refactoring
adou600 Jan 19, 2013
4666954
fix test after error handling improvement for route creation
adou600 Jan 19, 2013
9398e9d
remove elements linked to creation from the menu, not ready nor usabl…
adou600 Jan 19, 2013
4a7abd2
extract repeated methods in saucelabs tests
adou600 Jan 28, 2013
f3aa8db
WIP translated news
adou600 Jan 28, 2013
50e809d
finalization of the localizable news system
adou600 Jan 29, 2013
88124ff
merge master
adou600 Jan 29, 2013
22273cc
dependencies update with corresponding fixes
adou600 Jan 29, 2013
cc3d8a7
fix tests
adou600 Jan 29, 2013
f37eb7a
insert bug reference URL
adou600 Feb 3, 2013
e6a7c63
dependencies update and merge master
adou600 Mar 22, 2013
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ jackrabbit/
jackrabbit-standalone-*.jar
vagrant/.vagrant
app/bootstrap.php.cache
.idea/*
app/phpunit.xml

/bin/
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,31 @@ Functional tests are written with PHPUnit. Note that Bundles and Components are
phpunit -c app

[![Build Status](https://secure.travis-ci.org/symfony-cmf/cmf-sandbox.png?branch=master)](http://travis-ci.org/symfony-cmf/cmf-sandbox)

### Enable the Saucelabs tests

[Saucelabs](https://saucelabs.com) is used to test the frontend actions and especially the additional Javascript needed
to create content and routes with Create.js. To enable these tests (excluded by default):

Run ``php composer.phar install --dev`` to install the [sausage library](https://github.com/jlipps/sausage).

Create a free *Open Sauce* account on https://saucelabs.com and note your *username* and *access key*.

Run ``vendor/sauce/bin/sauce_config USERNAME ACCESS_KEY`` to configure the sausage library.

Open the sauce tunnel to be able to access the saucelabs cloud. To do so, follow the official documentation:
http://saucelabs.com/docs/connect

The Saucelabs tests have been written to be accessed with the URL http://cmf.lo/app_test.php. So make sure you can
access this URL locally on your machine. If needed, add an entry to your hosts file and configure your virtual host
accordingly ([see above](cmf-sandbox/tree/content-creation#access-by-web-browser)).

The last step is to enable the Saucelabs test cases in the `phpunit.xml.dist` file. The following line has to be commented:

<exclude>app/tests/Saucelabs</exclude>

The Saucelabs tests are included in the phpunit test cases. They can be run separately with the command

phpunit -c app/ --filter Saucelabs

Note that it can take several minutes to be completed and that a good Internet connection is recommended.
29 changes: 29 additions & 0 deletions app/config/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,11 @@ symfony_cmf_routing_extra:
Sandbox\MainBundle\Document\DemoClassContent: sandbox_main.controller:classAction
Symfony\Cmf\Bundle\RoutingExtraBundle\Document\RedirectRoute: symfony_cmf_routing_extra.redirect_controller:redirectAction
templates_by_class:
Sandbox\MainBundle\Document\NewsArticle: SandboxMainBundle:News:news_detail.html.twig
Sandbox\MainBundle\Document\CollectionPage: SandboxMainBundle:News:news_overview.{_format}.twig
Symfony\Cmf\Bundle\ContentBundle\Document\MultilangStaticContent: SandboxMainBundle:MultilangStaticContent:index.html.twig


symfony_cmf_simple_cms:
routing:
templates_by_class:
Expand All @@ -110,11 +113,26 @@ symfony_cmf_create:
phpcr_odm: true
map:
'http://rdfs.org/sioc/ns#Post': 'Symfony\Cmf\Bundle\ContentBundle\Document\MultilangStaticContent'
'http://schema.org/NewsArticle': 'Sandbox\MainBundle\Document\NewsArticle'
'http://schema.org/CollectionPage': 'Sandbox\MainBundle\Document\CollectionPage'
'http://cmf.symfony.com/CmfRoute': 'Symfony\Cmf\Bundle\RoutingExtraBundle\Document\Route'

rdfmapper:
'Symfony\Cmf\Bundle\RoutingExtraBundle\Document\Route': symfony_cmf_create.route_doctrine_phpcr_odm_mapper
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we integrate the "map" and "rdfmapper" map?

map:
    'http://rdfs.org/sioc/ns#Post':
        class: 'Symfony\Cmf\Bundle\ContentBundle\Document\MultilangStaticContent'
    'http://cmf.symfony.com/CmfRoute':
        class: 'Symfony\Cmf\Bundle\RoutingExtraBundle\Document\Route'
        rdfmapper: symfony_cmf_create.route_doctrine_phpcr_odm_mapper


use_coffee: %liip_vie.use_coffee%
image:
model_class: Symfony\Cmf\Bundle\CreateBundle\Document\Image
controller_class: Symfony\Cmf\Bundle\CreateBundle\Controller\PHPCRImageController

plain_text_types:
- dcterms:title
- cw:headline
- loc:name

create_routes_types:
- http://schema.org/NewsArticle

symfony_cmf_content:
multilang:
locales: %locales%
Expand Down Expand Up @@ -271,3 +289,14 @@ lunetics_locale:
# type: file_system
# nodes:
# type: file_system

fos_rest:
view:
formats:
rss: true
json: true
templating_formats:
rss: true
html: true
mime_types:
rss: 'application/rss+xml'
2 changes: 2 additions & 0 deletions app/phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
<directory>../vendor/symfony-cmf/src</directory>
<directory>../src/*/*Bundle/Tests</directory>
<directory>../src/*/Bundle/*Bundle/Tests</directory>
<!-- comment the following line to run Saucelabs tests -->
<exclude>app/tests/Saucelabs</exclude>
</testsuite>
</testsuites>

Expand Down
2 changes: 1 addition & 1 deletion app/tests/AdminTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public function testList()
$this->assertEquals(200, $response->getStatusCode());
$this->assertContains('Menu nodes', $response->getContent());

$menuCount = $this->isSearchSupported() ? 15 : 14;
$menuCount = $this->isSearchSupported() ? 16 : 15;
$this->assertContains("$menuCount results", $response->getContent());
$this->assertContains('Explicit template', $response->getContent());
}
Expand Down
11 changes: 11 additions & 0 deletions app/tests/FixturesLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Sandbox;

/**
* Class used by SaucelabsWebTestCase instances to load normal fixtures
* with the help of methods comming from WebTestCase
*/
class FixturesLoader extends WebTestCase
{
}
2 changes: 1 addition & 1 deletion app/tests/HomepageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function testContents()
$this->assertCount(1, $crawler->filter('h1:contains(Homepage)'));
$this->assertCount(1, $crawler->filter('h2:contains("Welcome to the Symfony CMF Demo")'));

$menuCount = $this->isSearchSupported() ? 14 : 13;
$menuCount = $this->isSearchSupported() ? 15 : 14;
$this->assertCount($menuCount, $crawler->filter('ul.menu_main li'));
}
}
152 changes: 152 additions & 0 deletions app/tests/NewsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
<?php

namespace Sandbox;

class NewsTest extends WebTestCase
{
public function testAddNews()
{
$client = $this->createClient();

$title = 'news title from testAddNews';
$formattedTitle = 'news-title-from-testAddNews';
$content = 'some new content from testAddNews';
$documentRequest = $this->generateCreateArticleRequest($title, $content);

$client->request('POST', '/en/symfony-cmf/create/document/_:bnode89', $documentRequest);
$this->assertEquals(200, $client->getResponse()->getStatusCode());
//the subject of the saved entity need to be set in the JSON response
$jsonResponse = json_decode($client->getResponse()->getContent());
$this->assertEquals($jsonResponse->{'@subject'},'</cms/content/news/' . $formattedTitle . '>');

$locales = array('en', 'fr', 'de');

foreach ($locales as $locale) {
$routeRequest = $this->generateCreateRouteRequest($formattedTitle, $locale);
$crawler = $client->request(
'POST',
'/' . $locale . ' /symfony-cmf/create/document/_:bnode26',
$routeRequest
);

$this->assertEquals(200, $client->getResponse()->getStatusCode());
//the subject of the saved entity need to be set in the JSON response
$jsonResponse = json_decode($client->getResponse()->getContent());
$this->assertEquals($jsonResponse->{'@subject'},'</cms/routes/'. $locale . '/news/' . $formattedTitle . '>');

$crawler = $client->request('GET', '/' . $locale . '/news/' . $formattedTitle . '');
$this->assertEquals(200, $client->getResponse()->getStatusCode());

$this->assertCount(1, $crawler->filter(sprintf('h2:contains("%s")', $title)));
$this->assertCount(1, $crawler->filter(sprintf('p:contains("%s")', $content)));
$this->assertCount(1, $crawler->filter(sprintf('div.subtitle:contains("%s")', 'Date: ' . date('Y-m-d'))));
}

//try to add a news with the same title, a collision on the node name should happen
$client->request('POST', '/en/symfony-cmf/create/document/_:bnode89', $documentRequest);
$this->assertEquals(500, $client->getResponse()->getStatusCode());
$this->assertEquals("The document 'http://schema.org/NewsArticle' could not be created", $client->getResponse()->getContent());
}

public function testUpdateNews()
{
self::$fixturesLoaded = false; // we only load fixtures once, but after this write test we want to refresh them
$client = $this->createClient();

//prepare the PUT request
$titleKey = '<http://schema.org/CreativeWork/headline>';
$title = 'updated title from testUpdateNews';

$contentKey = '<http://schema.org/Article/articleBody>';
$content = 'some updated content from testUpdateNews';

$subjectKey = '@subject';
$subject = '</cms/content/news/news-on-the-sandbox>';

$typeKey = '@type';
$type = '<<http://schema.org/NewsArticle>';

$crawler = $client->request('PUT', '/en/symfony-cmf/create/document/cms/content/news/news-on-the-sandbox',
array(
$titleKey => $title,
$contentKey => $content,
$subjectKey => $subject,
$typeKey => $type
)
);

$this->assertEquals(200, $client->getResponse()->getStatusCode());

//get the updated page and check if data has been updated
$crawler = $client->request('GET', '/en/news/news-on-the-sandbox');

$this->assertEquals(200, $client->getResponse()->getStatusCode());
$this->assertCount(1, $crawler->filter(sprintf('h2:contains("%s")', $title)));
$this->assertCount(1, $crawler->filter(sprintf('p:contains("%s")', $content)));
}

private function generateCreateRouteRequest($title, $locale)
{
//prepare the POST request for the new route in the current locale
$localeKey = '<http://cmf.symfony.com/CmfRoute/Locale>';

$nameKey = '<http://cmf.symfony.com/CmfRoute/Name>';
$nameValue = $title;

$parentKey = '<http://cmf.symfony.com/CmfRoute/Parent>';
$parentValue = '/cms/routes/' . $locale . '/news';

$routeContentKey = '<http://cmf.symfony.com/CmfRoute/RouteContent>';
$routeContentValue = '/cms/content/news/' . $title;

$partOfKey = '<http://purl.org/dc/terms/partOf>';
$partOfValue = '/cms/routes/' . $locale. '/news';

$subjectKey = '@subject';
$subjectValue = '_:bnode26';

$typeKey = '@type';
$typeValue = '<http://cmf.symfony.com/CmfRoute>';

$routeRequest = array(
$localeKey => $locale,
$nameKey => $nameValue,
$parentKey => $parentValue,
$routeContentKey => $routeContentValue,
$partOfKey => array($partOfValue),
$subjectKey => $subjectValue,
$typeKey => $typeValue
);

return $routeRequest;
}

private function generateCreateArticleRequest($title, $content)
{
//prepare the POST request
$partOfKey = '<http://purl.org/dc/terms/partOf>';
$partOf = '</cms/content/news>';

$titleKey = '<http://schema.org/CreativeWork/headline>';
$titleValue = $title;

$contentKey = '<http://schema.org/Article/articleBody>';
$contentValue = $content;

$subjectKey = '@subject';
$subject = '_:bnode89';

$typeKey = '@type';
$type = '<http://schema.org/NewsArticle>';

$request = array(
$partOfKey => array($partOf),
$titleKey => $titleValue,
$contentKey => $contentValue,
$subjectKey => $subject,
$typeKey => $type
);

return $request;
}
}
61 changes: 61 additions & 0 deletions app/tests/Saucelabs/HomepageEditUserTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace Sandbox\Saucelabs;

/**
* Use Saucelabs to test the edition of content with Create.js
*/
class HomepageEditUserTest extends SaucelabsWebTestCase
{
public function setUp()
{
parent::setUp();
$this->setBrowserUrl($this->homeUrl);
}

public function testEditHomepageContent()
{
//common variables
$originalTitle = 'Homepage';
$toAddToTitle = 'Updated title for ';
$updatedTitle = $toAddToTitle . $originalTitle;
$titleCss = 'div.inner h1:first-child';

//page loaded correctly?
$this->assertContains($originalTitle, $this->title());

//click on edit
$this->enterEditMode();

//cancel should now be in the button text
$cancelLink = $this->byId('midgardcreate-edit');
$this->assertContains("Cancel", $cancelLink->text());

//update the page title
$titleToEdit = $this->byCss($titleCss);
$titleToEdit->click();
$titleToEdit->value($toAddToTitle);

//click on save
$this->saveChanges();

//check the result
$this->assertContains($updatedTitle, $this->byCss($titleCss)->text());

//click on cancel
$this->leaveEditMode();

//reload the page to ensure the changes have been persisted
$this->url('/en');
$driver = $this;
$pageLoaded = function() use ($driver, $updatedTitle) {
//give some time to load the page
return ($driver->title() == $updatedTitle);
};
$this->spinAssert("Homepage was not loaded", $pageLoaded);

//updated title needs to be present in the page title and page content
$this->assertContains($updatedTitle, $this->title());
$this->assertContains($updatedTitle, $this->byCss($titleCss)->text());
}
}
Loading