9 | @Html.DisplayFor(x => area.ContentArea, new {Tag = area.AreaTag})
10 |
11 | }
12 | else
13 | {
14 | @await Html.PartialAsync("TemplateHint", string.Format(System.Globalization.CultureInfo.CurrentUICulture, LocalizationService.Current.GetString("/preview/norenderer"), Model.PreviewContent.Name, LocalizationService.Current.GetString(area.AreaName)))
15 | }
16 | }
17 |
18 | @if(!Model.Areas.Any())
19 | {
20 | @await Html.PartialAsync("TemplateHint", string.Format(System.Globalization.CultureInfo.CurrentUICulture, LocalizationService.Current.GetString("/preview/norendereratall"), Model.PreviewContent.Name))
21 | }
22 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/ProductPage/Index.cshtml:
--------------------------------------------------------------------------------
1 | @using Alloy.Sample
2 | @using Alloy.Sample.Helpers
3 | @model Alloy.Sample.Models.ViewModels.PageViewModel
4 |
5 | @{ Layout = "~/Views/Shared/Layouts/_TwoPlusOne.cshtml"; }
6 |
7 | x.CurrentPage.PageName)>@Model.CurrentPage.PageName
8 | x.CurrentPage.MetaDescription)>@Model.CurrentPage.MetaDescription
9 |
10 |
x.CurrentPage.MainBody)>
11 | @Html.DisplayFor(m => m.CurrentPage.MainBody)
12 |
13 |
14 | @Html.PropertyFor(x => x.CurrentPage.MainContentArea, new { CssClass = "row", Tag = Global.ContentAreaTags.TwoThirdsWidth })
15 |
16 | @section RelatedContent
17 | {
18 | x.CurrentPage.PageImage)>
19 |
)
20 |
21 |
22 |
23 |
x.CurrentPage.PageName)>@Model.CurrentPage.PageName
24 | @Html.PropertyFor(x => x.CurrentPage.UniqueSellingPoints)
25 |
26 |
27 | @Html.PropertyFor(x => x.CurrentPage.RelatedContentArea, new { CssClass = "row", Tag = Global.ContentAreaTags.OneThirdWidth })
28 | }
29 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/Blocks/ButtonBlock.cshtml:
--------------------------------------------------------------------------------
1 | @model Alloy.Sample.Models.Blocks.ButtonBlock
2 |
3 | m.ButtonText)>
4 | @{
5 | var buttonText = string.IsNullOrWhiteSpace(Model.ButtonText)
6 | ? LocalizationService.Current.GetString("/blocks/buttonblockcontrol/buttondefaulttext")
7 | : Model.ButtonText;
8 | }
9 | @buttonText
10 |
11 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/Blocks/EditorialBlock.cshtml:
--------------------------------------------------------------------------------
1 | @model Alloy.Sample.Models.Blocks.EditorialBlock
2 |
3 | x.MainBody)>
4 | @Html.DisplayFor(x => Model.MainBody)
5 |
6 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/Blocks/JumbotronBlockWide.cshtml:
--------------------------------------------------------------------------------
1 | @model Alloy.Sample.Models.Blocks.JumbotronBlock
2 |
3 |
4 |
5 | @Html.PropertyFor(m=>m.Image)
6 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/Blocks/NoRenderer.cshtml:
--------------------------------------------------------------------------------
1 | @await Html.PartialAsync("TemplateHint", Html.Translate("/blocks/norenderer/message").ToString())
2 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/Blocks/SiteLogotypeBlock.cshtml:
--------------------------------------------------------------------------------
1 | @model Alloy.Sample.Models.Blocks.SiteLogotypeBlock
2 |
3 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/Blocks/TeaserBlock.cshtml:
--------------------------------------------------------------------------------
1 | @using EPiServer.Core
2 | @using Alloy.Sample.Extensions
3 | @using Alloy.Sample.Helpers
4 |
5 | @model Alloy.Sample.Models.Blocks.TeaserBlock
6 |
7 |
8 | @*Link the teaser block only if a link has been set and not displayed in preview*@
9 | @using (Html.BeginConditionalLink
10 | (!ContentReference.IsNullOrEmpty(Model.Link) && !(Html.ViewContext.IsPreviewMode()),
11 | Url.PageLinkUrl(Model.Link),
12 | Model.Heading))
13 | {
14 |
x.Heading)>@Model.Heading
15 |
x.Text)>@Model.Text
16 |
x.Image)>
)
17 | }
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/Blocks/TeaserBlockWide.cshtml:
--------------------------------------------------------------------------------
1 | @using Alloy.Sample.Extensions
2 | @using Alloy.Sample.Helpers
3 | @model Alloy.Sample.Models.Blocks.TeaserBlock
4 |
5 |
6 | @*Link the teaser block only if a link has been set and not displayed in preview*@
7 | @using(Html.BeginConditionalLink(
8 | !ContentReference.IsNullOrEmpty(Model.Link) && !(Html.ViewContext.IsPreviewMode()),
9 | Url.PageLinkUrl(Model.Link),
10 | Model.Heading))
11 | {
12 |
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/Components/ContactBlock/Default.cshtml:
--------------------------------------------------------------------------------
1 | @model Alloy.Sample.Models.ViewModels.ContactBlockModel
2 |
3 |
14 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/Components/ImageFile/Default.cshtml:
--------------------------------------------------------------------------------
1 | @model Alloy.Sample.Models.ViewModels.ImageViewModel
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/Components/PageListBlock/Default.cshtml:
--------------------------------------------------------------------------------
1 | @using Alloy.Sample.Helpers
2 | @using Alloy.Sample.Models.Pages
3 | @model Alloy.Sample.Models.ViewModels.PageListModel
4 | @Html.FullRefreshPropertiesMetaData(new[] { "IncludePublishDate", "IncludeIntroduction", "Count", "SortOrder", "Root", "PageTypeFilter", "CategoryFilter", "Recursive" })
5 | x.Heading)>@Model.Heading
6 |
7 |
8 | @foreach(var page in Model.Pages)
9 | {
10 |
11 |
12 | @Html.PageLink(page)
13 |
14 | @if(Model.ShowPublishDate && page.StartPublish.HasValue)
15 | {
16 |
@Html.DisplayFor(x => page.StartPublish)
17 | }
18 | @if(Model.ShowIntroduction && page is SitePageData)
19 | {
20 | var withTeaserText = (SitePageData) page;
21 |
@withTeaserText.TeaserText
22 | }
23 |
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/Components/TestContentPage/Index.cshtml:
--------------------------------------------------------------------------------
1 | @using EPiServer
2 | @using EPiServer.ServiceLocation
3 | @using Alloy.Sample.Models.Pages
4 | @model Alloy.Sample.Models.ViewModels.PageViewModel
5 |
6 | @{
7 | var contentLoader = ServiceLocator.Current.GetInstance ();
8 | var block = contentLoader.Get(Model.CurrentPage.Reference);
9 | var block2 = contentLoader.Get(Model.CurrentPage.Reference);
10 | }
11 | @Model.CurrentPage.Title
12 |
13 |
14 | Display for:
15 | @Html.PropertyFor(m => m.CurrentPage.PageImage)
16 |
17 | @block.Title
18 | @block2.Title
19 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/Components/VideoFile/Default.cshtml:
--------------------------------------------------------------------------------
1 | @using EPiServer.Framework.Web.Resources
2 | @model Alloy.Sample.Models.ViewModels.VideoViewModel
3 | @{
4 | ClientResources.RequireScript(Href("~/jwplayer/jwplayer.js"));
5 |
6 | //The video element's ID needs to be unique in order for several video blocks and possible the same video block, to work on the same page
7 | var containerId = "video-container-" + Guid.NewGuid().GetHashCode();
8 | }
9 | @Html.FullRefreshPropertiesMetaData(new []{"Url"})
10 | m.Url)>
11 |
14 |
15 |
30 |
31 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/DisplayTemplates/ContactPage.cshtml:
--------------------------------------------------------------------------------
1 | @model Alloy.Sample.Models.Pages.ContactPage
2 |
3 |
4 | @if(Model != null)
5 | {
6 | @Model.PageName
7 | @Html.Translate("/contact/phone")@: : @Model.Phone
8 | @Html.Translate("/contact/email")@: : @Html.DisplayFor(m => m.Email)
9 | }
10 | else
11 | {
12 | @Html.Translate("/contact/noneselected")
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/DisplayTemplates/DateTime.cshtml:
--------------------------------------------------------------------------------
1 | @model DateTime
2 | @Model.ToString("d MMMM yyyy")
3 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/DisplayTemplates/StringsCollection.cshtml:
--------------------------------------------------------------------------------
1 | @model IEnumerable
2 | @if(Model != null && Model.Any())
3 | {
4 |
5 | @foreach(var stringValue in Model)
6 | {
7 | - @stringValue
8 | }
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/DisplayTemplates/_ReadMe.txt:
--------------------------------------------------------------------------------
1 | The views in this folder are used when rendering properties using Html.DisplayFor and Html.PropertyFor.
2 | Display templates are selected based on the type name of the property and, optionally, by UIHint and DataType attributes added to the property.
3 | Note that the CMS adds a number of view templates which do not exist in this folder but found through a view engine which the CMS adds at start up.
4 | Those view templates can be found in \Application\Util\Views\Shared\DisplayTemplates. Views in this folder takes precedence meaning
5 | that we can override those templates, which is currently done for content areas.
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/Layouts/_LeftNavigation.cshtml:
--------------------------------------------------------------------------------
1 | @model Alloy.Sample.Models.ViewModels.IPageViewModel
2 |
3 | @{ Layout = "~/Views/Shared/Layouts/_Root.cshtml"; }
4 |
5 | @{await Html.RenderPartialAsync("Breadcrumbs", Model);}
6 |
7 |
8 |
9 |
10 |
11 | @{await Html.RenderPartialAsync("SubNavigation", Model);}
12 | @RenderSection("RelatedContent", false)
13 |
14 |
15 |
16 |
17 |
18 | @RenderBody()
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/Layouts/_TwoPlusOne.cshtml:
--------------------------------------------------------------------------------
1 | @using Alloy.Sample
2 | @using Alloy.Sample.Models.Pages
3 | @model Alloy.Sample.Models.ViewModels.IPageViewModel
4 | @{ Layout = "~/Views/Shared/Layouts/_Root.cshtml"; }
5 |
6 | @{await Html.RenderPartialAsync("Breadcrumbs");}
7 |
8 |
9 |
10 |
11 | @RenderBody()
12 |
13 |
14 |
15 | @if (IsSectionDefined("RelatedContent"))
16 | {
17 | @RenderSection("RelatedContent")
18 | }
19 | else if (Model.CurrentPage is IHasRelatedContent)
20 | {
21 | @Html.PropertyFor(x => ((IHasRelatedContent)x.CurrentPage).RelatedContentArea, new { CssClass = "row", Tag = Global.ContentAreaTags.OneThirdWidth })
22 | }
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/PagePartials/ContactPage.cshtml:
--------------------------------------------------------------------------------
1 | @model Alloy.Sample.Models.Pages.ContactPage
2 |
3 |
4 |
)
5 |
@Model.PageName
6 |
@Model.TeaserText
7 |
8 | @Html.Translate("/contact/email"): @Html.DisplayFor(x => x.Email)
9 | @Html.Translate("/contact/phone"): @Model.Phone
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/PagePartials/ContactPageWide.cshtml:
--------------------------------------------------------------------------------
1 | @model Alloy.Sample.Models.Pages.ContactPage
2 |
15 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/PagePartials/Page.cshtml:
--------------------------------------------------------------------------------
1 | @using EPiServer.Core
2 | @using Alloy.Sample.Helpers
3 | @model Alloy.Sample.Models.Pages.SitePageData
4 |
5 |
6 | @using(Html.BeginConditionalLink(Model.HasTemplate(), Url.PageLinkUrl(Model), Model.PageName))
7 | {
8 |
@Model.PageName
9 |
@Model.TeaserText
10 | @Html.DisplayFor(m => m.PageImage)
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/PagePartials/PageWide.cshtml:
--------------------------------------------------------------------------------
1 | @using EPiServer.Core
2 | @using Alloy.Sample.Helpers
3 | @model Alloy.Sample.Models.Pages.SitePageData
4 |
5 | @using(Html.BeginConditionalLink(Model.HasTemplate(), Url.PageLinkUrl(Model), Model.PageName))
6 | {
7 |
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/Readonly.cshtml:
--------------------------------------------------------------------------------
1 | @model Alloy.Sample.Models.ViewModels.IPageViewModel
2 |
3 | @Html.Translate("/Readonly/Message")
4 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/TemplateError.cshtml:
--------------------------------------------------------------------------------
1 | @model Alloy.Sample.Models.ViewModels.ContentRenderingErrorModel
2 |
3 |
@string.Format(System.Globalization.CultureInfo.CurrentUICulture, LocalizationService.Current.GetString("/renderingerror/heading"), Model.ContentTypeName, Model.ContentName)
4 |
5 | @Model.Exception.Message
6 | @Model.Exception.StackTrace
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/Shared/TemplateHint.cshtml:
--------------------------------------------------------------------------------
1 | @model string
2 | @Model
3 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/StandardPage/Index.cshtml:
--------------------------------------------------------------------------------
1 | @using Alloy.Sample
2 | @model Alloy.Sample.Models.ViewModels.PageViewModel
3 |
4 | @{ Layout = "~/Views/Shared/Layouts/_LeftNavigation.cshtml"; }
5 |
6 | x.CurrentPage.PageName)>@Model.CurrentPage.PageName
7 | x.CurrentPage.MetaDescription)>@Model.CurrentPage.MetaDescription
8 |
9 |
x.CurrentPage.MainBody)>
10 | @Html.DisplayFor(m => m.CurrentPage.MainBody)
11 |
12 |
13 | @Html.PropertyFor(x => x.CurrentPage.MainContentArea, new { CssClass = "row", Tag = Global.ContentAreaTags.TwoThirdsWidth })
14 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/StartPage/Index.cshtml:
--------------------------------------------------------------------------------
1 | @using Alloy.Sample
2 | @model Alloy.Sample.Models.ViewModels.PageViewModel
3 |
4 | @Html.PropertyFor(x => x.CurrentPage.MainContentArea, new { CssClass = "row equal-height", tag = Global.ContentAreaTags.FullWidth })
5 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/_ReadMe.txt:
--------------------------------------------------------------------------------
1 | View locations in Alloy follows a number of conventions in addition to the default ASP.NET MVC conventions:
2 | * Views for pages and blocks with their own controllers use standard ASP.NET MVC conventions - /.cshtml
3 | * Page types which don't have their own controller are mapped to /Index.cshtml by DefaultPageController
4 | * Views for block types which don't have their own controllers are found in Shared/Blocks
5 | * Partial views for page types which don't have their own controllers for partial requests are found in Shared/PagePartials
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/_ViewImports.cshtml:
--------------------------------------------------------------------------------
1 | @using EPiServer.Framework.Localization
2 | @using EPiServer.Web.Mvc.Html
3 | @using EPiServer.Shell.Web.Mvc.Html
4 | @using EPiServer.Core
5 | @using EPiServer.Web
6 | @using EPiServer.Web.Mvc
7 | @using EPiServer.Web.Routing
8 | @using Microsoft.AspNetCore.Mvc.Razor
9 | @using Microsoft.AspNetCore.Html
10 |
11 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
12 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/Views/_viewstart.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | Layout = "~/Views/Shared/Layouts/_Root.cshtml";
3 | }
4 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "EPiServer": "Information",
7 | "Microsoft.Hosting.Lifetime": "Information"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/bundleconfig.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "outputFileName": "wwwroot/css/css.min.css",
4 | "inputFiles": [
5 | "wwwroot/css/bootstrap.css",
6 | "wwwroot/css/bootstrap-responsive.css",
7 | "wwwroot/css/media.css",
8 | "wwwroot/css/style.css",
9 | "wwwroot/css/editmode.css"
10 | ]
11 | },
12 | {
13 | "outputFileName": "wwwroot/js/script.min.js",
14 | "inputFiles": [
15 | "wwwroot/js/jquery.js",
16 | "wwwroot/js/bootstrap.js"
17 | ],
18 | "minify": {
19 | "enabled": true,
20 | "renameLocals": true
21 | },
22 | "sourceMap": false
23 | }
24 | ]
--------------------------------------------------------------------------------
/src/Alloy.Sample/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 | services:
3 | sql:
4 | build:
5 | dockerfile: ./docker/Sql.Dockerfile
6 | context: .
7 | # comment out below lines if you want to expose sql server port for using with other tool like sql server managemnent studio
8 | # ports:
9 | # - "1433:1433"
10 | environment:
11 | SA_PASSWORD: ${sa_password}
12 | ACCEPT_EULA: "Y"
13 | DATABASE_NAME: ${database_name}
14 | image: alloy/db:${sql_tag}
15 | web:
16 | build:
17 | dockerfile: ./docker/Web.Dockerfile
18 | context: .
19 | ports:
20 | - "${site_port}:8000"
21 | environment:
22 | ConnectionStrings__EPiServerDB: "Server=sql;Database=${database_name};User Id=sa;Password=${sa_password};MultipleActiveResultSets=True;"
23 | depends_on:
24 | - sql
25 | image: alloy/web:${web_tag}
26 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/docker/Sql.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/mssql/server:2019-latest AS base
2 |
3 | USER root
4 |
5 | ENV ACCEPT_EULA=Y
6 | ENV MSSQL_TCP_PORT=1433
7 | EXPOSE 1433
8 |
9 | WORKDIR /src
10 | COPY ./docker/build-script/attach_db.sh /docker/attach_db.sh
11 | COPY ./App_Data/Alloy.mdf /docker/Alloy.mdf
12 |
13 | RUN chmod -R 777 /docker/.
14 |
15 | ENTRYPOINT /docker/attach_db.sh & /opt/mssql/bin/sqlservr
16 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/docker/Web.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
2 | WORKDIR /app
3 | EXPOSE 8000
4 |
5 | FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
6 | WORKDIR /src
7 | COPY . .
8 | RUN dotnet restore "Alloy.Sample.csproj"
9 |
10 | RUN dotnet build "Alloy.Sample.csproj" -c Release -o /app/build
11 |
12 | FROM build AS publish
13 | RUN dotnet publish "Alloy.Sample.csproj" -c Release -o /app/publish
14 | COPY ./docker/build-script/wait_sqlserver_start_and_attachdb.sh /app/publish/wait_sqlserver_start_and_attachdb.sh
15 | COPY ./App_Data/DefaultSiteContent.episerverdata /app/publish/App_Data/DefaultSiteContent.episerverdata
16 |
17 | FROM base AS final
18 | WORKDIR /app
19 | COPY --from=publish /app/publish .
20 | #wait sql server container start and attach alloy database then start web
21 | ENTRYPOINT ./wait_sqlserver_start_and_attachdb.sh
22 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/docker/build-script/attach_db.sh:
--------------------------------------------------------------------------------
1 | sleep 30s
2 | /opt/mssql-tools/bin/sqlcmd -S . -U sa -P ${SA_PASSWORD} \
3 | -Q "CREATE DATABASE [${DATABASE_NAME}] ON (FILENAME ='/docker/Alloy.mdf') FOR ATTACH"
--------------------------------------------------------------------------------
/src/Alloy.Sample/docker/build-script/wait_sqlserver_start_and_attachdb.sh:
--------------------------------------------------------------------------------
1 |
2 | sleep 120s
3 | echo "Connection string:" $ConnectionStrings__EPiServerDB
4 | echo "Site port:" $site_port
5 | dotnet Alloy.Sample.dll
6 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/docker/run-script/build.sh:
--------------------------------------------------------------------------------
1 | docker load -i alloy-db.tar
2 | docker load -i alloy-web.tar
--------------------------------------------------------------------------------
/src/Alloy.Sample/docker/run-script/build_web_only.sh:
--------------------------------------------------------------------------------
1 | docker load -i alloy-web.tar
--------------------------------------------------------------------------------
/src/Alloy.Sample/docker/run-script/run.sh:
--------------------------------------------------------------------------------
1 | docker-compose -f docker-compose.yml up -d
--------------------------------------------------------------------------------
/src/Alloy.Sample/docker/run-script/stop.sh:
--------------------------------------------------------------------------------
1 | docker-compose -f docker-compose.yml down
--------------------------------------------------------------------------------
/src/Alloy.Sample/docker/run-script/stop_web_only.sh:
--------------------------------------------------------------------------------
1 | docker-compose rm -f -s -v web
--------------------------------------------------------------------------------
/src/Alloy.Sample/favicon.ico:
--------------------------------------------------------------------------------
1 | h ( ... >>> Ɋ9 777 000 $$$ 666 !!! ###
--------------------------------------------------------------------------------
/src/Alloy.Sample/module.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/modulesbin/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/modulesbin/.gitkeep
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/ClientResources/Images/icons/layoutIcons24x24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/ClientResources/Images/icons/layoutIcons24x24.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/ClientResources/Styles/LayoutIcons.css:
--------------------------------------------------------------------------------
1 | .Sleek .epi-icon__layout--full {
2 | background: url('../Images/icons/layoutIcons24x24.png') 0px -24px no-repeat;
3 | height: 24px;
4 | width: 24px;
5 | }
6 | .Sleek .epi-icon__layout--half {
7 | background: url('../Images/icons/layoutIcons24x24.png') 0px -48px no-repeat;
8 | height: 24px;
9 | width: 24px;
10 | }
11 | .Sleek .epi-icon__layout--two-thirds {
12 | background: url('../Images/icons/layoutIcons24x24.png') 0px -72px no-repeat;
13 | height: 24px;
14 | width: 24px;
15 | }
16 | .Sleek .epi-icon__layout--one-third {
17 | background: url('../Images/icons/layoutIcons24x24.png') 0px -96px no-repeat;
18 | height: 24px;
19 | width: 24px;
20 | }
21 | .Sleek .epi-icon__layout--one-quarter {
22 | background: url('../Images/icons/layoutIcons24x24.png') 0px -120px no-repeat;
23 | height: 24px;
24 | width: 24px;
25 | }
26 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/ClientResources/Styles/Styles.css:
--------------------------------------------------------------------------------
1 | @import url("LayoutIcons.css");
2 |
3 | .epiStringList .dijitTextArea {
4 | width: 250px;
5 | }
6 |
7 | .epiStringList .epiStringListError .dijitTextArea {
8 | border: solid 1px #d46464;
9 | }
10 |
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/css/editmode.css:
--------------------------------------------------------------------------------
1 | /* CSS specific to edit mode, such as help content displayed to the editor */
2 |
3 | .alert-info
4 | {
5 | border-color: #B8C0C5;
6 | color: black;
7 | font-family: Verdana;
8 | font-size: 1em;
9 | font-style: italic;
10 | background-color: #B8C0C5;
11 | box-shadow: 3px 3px 5px #CCC;
12 | text-align: center;
13 | }
14 |
15 | .alert-error p {
16 | text-align: left;
17 | }
18 |
19 | .alert-error .heading {
20 | font-weight: bold;
21 | color: #ff0000;
22 | }
23 |
24 | .alert-error .details {
25 | font-size: 0.8em;
26 | max-height: 100px;
27 | overflow: scroll;
28 | }
29 |
30 | .header.dim {
31 | margin: 2% 0;
32 | opacity: 0.3;
33 | }
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/css/editor.css:
--------------------------------------------------------------------------------
1 | /* Styles used by the TinyMCE editor */
2 |
3 | h2 {EditMenuName:Header 2;}
4 | h3 {EditMenuName:Header 3;}
5 |
6 | /*Block Preview*/
7 | .alert-info {
8 | background-color: #FFF8AA;
9 | border-color: #858585;
10 | color: #000000;
11 | font-family: Verdana;
12 | font-size: 12px;
13 | }
14 |
15 | .header.dim {
16 | margin: 2% 0;
17 | opacity: 0.3;
18 | }
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/New_FDT_Press_Contact_.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/New_FDT_Press_Contact_.JPG
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/carouselbackground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/carouselbackground.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/contact.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/contact.jpg
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/exampelspan4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/exampelspan4.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/experts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/experts.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/fallows-media-wide.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/fallows-media-wide.jpg
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/leader.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/leader.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/leader2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/leader2.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/logotype.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/logotype.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/meet.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/meet.jpg
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/page-type-thumbnail-article.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/page-type-thumbnail-article.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/page-type-thumbnail-contact.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/page-type-thumbnail-contact.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/page-type-thumbnail-product.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/page-type-thumbnail-product.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/page-type-thumbnail-standard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/page-type-thumbnail-standard.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/page-type-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/page-type-thumbnail.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/person.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/person.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/plan.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/plan.jpg
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/play.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/playInactive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/playInactive.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/productLandingv2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/productLandingv2.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/searchbutton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/searchbutton.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/searchbuttonsmall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/searchbuttonsmall.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/gfx/track.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/gfx/track.jpg
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/img/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/img/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/img/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/img/glyphicons-halflings.png
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/jwplayer/player.swf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/jwplayer/player.swf
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/jwplayer/preview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/jwplayer/preview.jpg
--------------------------------------------------------------------------------
/src/Alloy.Sample/wwwroot/jwplayer/video.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/src/Alloy.Sample/wwwroot/jwplayer/video.mp4
--------------------------------------------------------------------------------
/test.cmd:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | SETLOCAL
3 |
4 | SET PATH=.\.ci\tools\;%PATH%
5 |
6 | REM Set Release or Debug configuration.
7 | IF "%1"=="Release" (set CONFIGURATION=Release) ELSE (set CONFIGURATION=Debug)
8 | ECHO Testing in %CONFIGURATION%
9 |
10 | ECHO Running c# tests
11 | CALL dotnet test test\Advanced.CMS.AdvancedReviews.IntegrationTests.Basic\Advanced.CMS.AdvancedReviews.IntegrationTests.Basic.csproj -c %CONFIGURATION%
12 | CALL dotnet test test\Advanced.CMS.AdvancedReviews.IntegrationTests.PinSecurity\Advanced.CMS.AdvancedReviews.IntegrationTests.PinSecurity.csproj -c %CONFIGURATION%
13 | IF %errorlevel% NEQ 0 EXIT /B %errorlevel%
14 |
15 | EXIT /B %ERRORLEVEL%
16 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.AdvancedReviews.IntegrationTests.Basic/Advanced.CMS.AdvancedReviews.IntegrationTests.Basic.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net6.0
6 | false
7 | True
8 | False
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.AdvancedReviews.IntegrationTests.Basic/IntegrationTestCollection.cs:
--------------------------------------------------------------------------------
1 | using EPiServer.ServiceLocation;
2 | using Xunit;
3 |
4 | namespace Advanced.CMS.AdvancedReviews.IntegrationTests.Basic;
5 |
6 | [CollectionDefinition(Name, DisableParallelization = true)]
7 | public class IntegrationTestCollection : ICollectionFixture
8 | {
9 | public const string Name = "Advanced Reviews Test Collection";
10 | }
11 |
12 | [Collection(IntegrationTestCollection.Name)]
13 | public class IntegrationTestCollectionBaseClassFixture : IClassFixture
14 | {
15 | protected readonly SiteFixture _siteFixture;
16 | protected readonly TestScenarioBuilderFactory _testScenarioBuilderFactory;
17 |
18 | public IntegrationTestCollectionBaseClassFixture(SiteFixture siteFixture)
19 | {
20 | _siteFixture = siteFixture;
21 | _testScenarioBuilderFactory = ServiceLocator.Current.GetInstance();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.AdvancedReviews.IntegrationTests.Basic/NoEveryoneAccess.cs:
--------------------------------------------------------------------------------
1 | using System.Net;
2 | using System.Net.Http;
3 | using System.Threading.Tasks;
4 | using Xunit;
5 |
6 | namespace Advanced.CMS.AdvancedReviews.IntegrationTests.Basic;
7 |
8 | public class NoEveryoneAccess : IntegrationTestCollectionBaseClassFixture
9 | {
10 | public NoEveryoneAccess(SiteFixture siteFixture) : base(siteFixture)
11 | {
12 | }
13 |
14 | [Fact]
15 | public async Task When_Creating_Token_For_Page_Without_Everyone_Access_It_Returns_200()
16 | {
17 | var testEnvironment = _testScenarioBuilderFactory.GetBuilder().Init().WithoutEveryoneAccess().WithViewPin().Build();
18 |
19 | var message = new HttpRequestMessage(HttpMethod.Get, testEnvironment.ExternalReviewLink.LinkUrl);
20 | var response = await _siteFixture.Client.SendAsync(message);
21 | await response.Content.ReadAsStringAsync();
22 | Assert.Equal(HttpStatusCode.OK, response.StatusCode);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.AdvancedReviews.IntegrationTests.Basic/PreviewingLastContentVersion.cs:
--------------------------------------------------------------------------------
1 | namespace Advanced.CMS.AdvancedReviews.IntegrationTests.Basic;
2 | /*
3 | GIVEN:
4 | - draft page
5 | - external view link to page
6 | WHEN:
7 | - page is referencing draft content
8 | THEN:
9 | - should always show latest page version
10 | */
11 |
12 | public class PreviewingLastContentVersion
13 | {
14 | // create REFERENCED page draft
15 |
16 | // create MAIN draft page
17 |
18 | // reference REFERENCED page in MAIN page ContentArea
19 |
20 | // create external link for MAIN page
21 |
22 | // ASSERT REFERENCED page is visible
23 |
24 | // publish REFERENCED page
25 |
26 | // ASSERT REFERENCED page is visible
27 |
28 | // update REFERENCED page, but don't publish
29 |
30 | // ASSERT REFERENCED page is visible
31 | }
32 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.AdvancedReviews.IntegrationTests.Basic/PublishedPageWithDraftReferencesTests.cs:
--------------------------------------------------------------------------------
1 | namespace Advanced.CMS.AdvancedReviews.IntegrationTests.Basic;
2 | /*
3 | GIVEN:
4 | - draft/published page with ContentArea, ContentReference, LinkItemCollection
5 | - external view link to page
6 | WHEN:
7 | - page is referencing unpublished content in properties
8 | THEN:
9 | - should show draft references
10 | */
11 |
12 | public class PublishedPageWithDraftReferencesTests
13 | {
14 | // create 3 draft pages
15 |
16 | // create MAIN draft page
17 |
18 | // reference 3 draft pages in ContentArea, ContentReference and LinkItemCollection
19 |
20 | // create external link
21 |
22 | // ASSERT draft content is visible on page
23 |
24 | // publish MAIN page
25 |
26 | // ASSERT draft content is visible on page
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.AdvancedReviews.IntegrationTests.Basic/SinglePageWithLanguagesTests.cs:
--------------------------------------------------------------------------------
1 | namespace Advanced.CMS.AdvancedReviews.IntegrationTests.Basic;
2 | /*
3 | GIVEN:
4 | - draft page
5 | - external view link to page
6 | WHEN:
7 | - page is translated
8 | THEN:
9 | - should load proper draft version
10 | */
11 |
12 | public class SinglePageWithLanguagesTests
13 | {
14 | // create draft page
15 |
16 | // create external link for page
17 |
18 | // translate page
19 |
20 | // create external link for translated page
21 |
22 | // ASSERT main branch link shows proper data
23 |
24 | // ASSERT translated page shows proper data
25 |
26 | // publish main branch
27 |
28 | // change main branch data
29 |
30 | // publish translated page
31 |
32 | // change translated page data
33 |
34 | // ASSERT main branch link shows proper data
35 |
36 | // ASSERT translated page shows proper data
37 | }
38 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.AdvancedReviews.IntegrationTests.Basic/SiteFixture.cs:
--------------------------------------------------------------------------------
1 | namespace Advanced.CMS.AdvancedReviews.IntegrationTests.Basic;
2 |
3 | public class SiteFixture : SiteFixtureBase
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.AdvancedReviews.IntegrationTests.Basic/TinyMceShowDraftLinksTests.cs:
--------------------------------------------------------------------------------
1 | namespace Advanced.CMS.AdvancedReviews.IntegrationTests.Basic;
2 | /*
3 | GIVEN:
4 | - draft page with TinyMce
5 | - external view link to page
6 | WHEN:
7 | - TinyMce property contains unpublished images
8 | THEN:
9 | - should show draft content in TinyMce
10 | */
11 |
12 | public class TinyMceShowDraftLinksTests
13 | {
14 | // create an image
15 |
16 | // create MAIN draft page
17 |
18 | // add image link to TinyMce
19 |
20 | // create external link
21 |
22 | // ASSERT draft image is visible
23 | }
24 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.AdvancedReviews.IntegrationTests.Basic/TokenExpiration.cs:
--------------------------------------------------------------------------------
1 | using System.Net;
2 | using System.Net.Http;
3 | using System.Threading.Tasks;
4 | using Xunit;
5 |
6 | namespace Advanced.CMS.AdvancedReviews.IntegrationTests.Basic;
7 |
8 | public class TokenExpiration : IntegrationTestCollectionBaseClassFixture
9 | {
10 | public TokenExpiration(SiteFixture siteFixture) : base(siteFixture)
11 | {
12 | }
13 |
14 | [Fact]
15 | public async Task When_DraftPage_Created_Link_Is_Expired_It_Returns_404()
16 | {
17 | var testEnvironment = _testScenarioBuilderFactory.GetBuilder().Init().WithViewPin().PinExpired().Build();
18 |
19 | var messageAfterTokenExpiration = new HttpRequestMessage(HttpMethod.Get, testEnvironment.ExternalReviewLink.LinkUrl);
20 | var responseAfterTokenExpiration = await _siteFixture.Client.SendAsync(messageAfterTokenExpiration);
21 | await responseAfterTokenExpiration.Content.ReadAsStringAsync();
22 | Assert.Equal(HttpStatusCode.NotFound, responseAfterTokenExpiration.StatusCode);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.AdvancedReviews.IntegrationTests.PinSecurity/Advanced.CMS.AdvancedReviews.IntegrationTests.PinSecurity.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | false
6 | True
7 | False
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.AdvancedReviews.IntegrationTests.PinSecurity/IntegrationTestCollection.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace Advanced.CMS.AdvancedReviews.IntegrationTests.PinSecurity;
4 |
5 | [CollectionDefinition(Name, DisableParallelization = true)]
6 | public class IntegrationTestCollectionWithPinSecurity : ICollectionFixture
7 | {
8 | public const string Name = "Advanced Reviews Test Collection With Pin Security";
9 | }
10 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.AdvancedReviews.IntegrationTests.PinSecurity/ObjectExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Reflection;
4 |
5 | namespace Advanced.CMS.AdvancedReviews.IntegrationTests.PinSecurity;
6 |
7 | public static class ObjectExtensions
8 | {
9 | public static IDictionary AsDictionary(this object source, BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
10 | {
11 | return (IDictionary)source.GetType().GetProperties(bindingAttr).ToDictionary
12 | (
13 | propInfo => propInfo.Name,
14 | propInfo => (T)propInfo.GetValue(source, null));
15 |
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.AdvancedReviews.IntegrationTests.PinSecurity/SiteFixtureWithPinSecurity.cs:
--------------------------------------------------------------------------------
1 | using Advanced.CMS.ExternalReviews;
2 | using Microsoft.Extensions.DependencyInjection;
3 |
4 | namespace Advanced.CMS.AdvancedReviews.IntegrationTests.PinSecurity;
5 |
6 | public class SiteFixtureWithPinSecurity : SiteFixtureBase
7 | {
8 | public SiteFixtureWithPinSecurity() : base(OptionsCallback)
9 | {
10 | }
11 |
12 | private static void OptionsCallback(ExternalReviewOptions options)
13 | {
14 | options.PinCodeSecurity.Enabled = true;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.AdvancedReviews.IntegrationTests/Advanced.CMS.AdvancedReviews.IntegrationTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net6.0
6 | false
7 | True
8 | False
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.AdvancedReviews.IntegrationTests/Assets/db_template.mdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/advanced-cms/advanced-reviews/2cc087131f15c2b71bd85ac364c05fd1fed079a4/test/Advanced.CMS.AdvancedReviews.IntegrationTests/Assets/db_template.mdf
--------------------------------------------------------------------------------
/test/Advanced.CMS.AdvancedReviews.IntegrationTests/TestEnvironment.cs:
--------------------------------------------------------------------------------
1 | using Advanced.CMS.ExternalReviews.ReviewLinksRepository;
2 | using TestSite.Models;
3 |
4 | namespace Advanced.CMS.AdvancedReviews.IntegrationTests;
5 |
6 | public class TestEnvironment
7 | {
8 | public TestEnvironment(StandardPage page, ExternalReviewLink externalReviewLink)
9 | {
10 | Page = page;
11 | ExternalReviewLink = externalReviewLink;
12 | }
13 |
14 | public StandardPage Page { get; set; }
15 |
16 | public ExternalReviewLink ExternalReviewLink { get; set; }
17 | }
18 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.IntegrationTests/Advanced.CMS.IntegrationTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net6.0
6 | false
7 | True
8 | False
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.IntegrationTests/CmsDatabaseFixture.cs:
--------------------------------------------------------------------------------
1 | namespace Advanced.CMS.IntegrationTests
2 | {
3 | public sealed class CmsDatabaseFixture : DatabaseFixture
4 | {
5 | public CmsDatabaseFixture(string databaseMdfTemplateFile, string destinationDatabaseFile)
6 | {
7 | CMS_MDF_FILE_PATH = databaseMdfTemplateFile;
8 | DESTINATION_MDF_PATH = destinationDatabaseFile;
9 | DropExistingDatabases(DESTINATION_MDF_PATH);
10 | CopyDatabaseFiles();
11 | SetFolderAccess();
12 | CreateDatabase(DESTINATION_MDF_PATH);
13 | }
14 | protected override string CMS_MDF_FILE_PATH { get; }
15 | protected override string DESTINATION_MDF_PATH { get; }
16 | protected override string CONNECTION_STRING_TEMPLATE { get; }
17 |
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.IntegrationTests/ServiceMocks/MockableContentAccessChecker.cs:
--------------------------------------------------------------------------------
1 | using EPiServer;
2 | using EPiServer.Core;
3 | using EPiServer.Core.Internal;
4 | using EPiServer.Security;
5 |
6 | namespace Advanced.CMS.IntegrationTests.ServiceMocks;
7 |
8 | public class MockableContentAccessChecker : ContentAccessChecker
9 | {
10 | public bool Enabled { get; set; }
11 |
12 | public MockableContentAccessChecker(IContentLoader contentLoader, IPrincipalAccessor principalAccessor) : base(
13 | contentLoader, principalAccessor)
14 | {
15 | }
16 |
17 | public override bool HasSufficientAccess(ContentProvider provider, ContentReference contentLink, AccessLevel access)
18 | {
19 | return Enabled || base.HasSufficientAccess(provider, contentLink, access);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.IntegrationTests/ServiceMocks/MockableCurrentProject.cs:
--------------------------------------------------------------------------------
1 | using EPiServer.Cms.Shell.UI.Rest.Projects;
2 | using EPiServer.DataAbstraction;
3 | using EPiServer.ServiceLocation;
4 | using Microsoft.AspNetCore.Http;
5 |
6 | namespace Advanced.CMS.IntegrationTests.ServiceMocks;
7 |
8 | public class MockableCurrentProject : CurrentProject
9 | {
10 | private int? projectId;
11 |
12 | public MockableCurrentProject(IHttpContextAccessor httpContextAccessor,
13 | ServiceAccessor projectRepositoryAccessor) : base(httpContextAccessor,
14 | projectRepositoryAccessor)
15 | {
16 | }
17 |
18 | public override int? ProjectId => projectId;
19 |
20 | public void SetProject(int? value)
21 | {
22 | projectId = value;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.IntegrationTests/ServiceMocks/MockableProjectLoaderService.cs:
--------------------------------------------------------------------------------
1 | using EPiServer.Cms.Shell.UI.Rest.Projects;
2 | using EPiServer.Cms.Shell.UI.Rest.Projects.Internal;
3 | using EPiServer.Data;
4 | using EPiServer.DataAbstraction;
5 | using EPiServer.ServiceLocation;
6 |
7 | namespace Advanced.CMS.IntegrationTests.ServiceMocks;
8 |
9 | public class MockableProjectLoaderService : ProjectLoaderService
10 | {
11 | public MockableProjectLoaderService(ProjectRepository projectRepository,
12 | ISiteConfigurationRepository siteConfigurationRepository,
13 | ProjectUIOptions projectUIOptions, IDatabaseMode databaseMode) : base(projectRepository,
14 | ServiceLocator.Current.GetInstance(),
15 | ServiceLocator.Current.GetInstance(),
16 | siteConfigurationRepository, projectUIOptions, databaseMode)
17 | {
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.IntegrationTests/ServiceMocks/MockableProjectService.cs:
--------------------------------------------------------------------------------
1 | using EPiServer.Cms.Shell.UI.Rest;
2 | using EPiServer.Cms.Shell.UI.Rest.Approvals.Internal;
3 | using EPiServer.Cms.Shell.UI.Rest.Projects;
4 | using EPiServer.Cms.Shell.UI.Rest.Projects.Internal;
5 | using EPiServer.Core;
6 | using EPiServer.Data;
7 | using EPiServer.DataAbstraction;
8 | using EPiServer.Framework.Localization;
9 | using EPiServer.ServiceLocation;
10 |
11 | namespace Advanced.CMS.IntegrationTests.ServiceMocks;
12 |
13 | public class MockableProjectService : ProjectService
14 | {
15 | public MockableProjectService(ProjectRepository projectRepository, ProjectPublisher projectPublisher,
16 | IContentChangeManager contentChangeManager,
17 | LanguageSelectorFactory languageSelectorFactory,
18 | ISiteConfigurationRepository siteConfigurationRepository, ApprovalService approvalService,
19 | LocalizationService localizationService, ProjectUIOptions projectUIOptions, IDatabaseMode databaseMode) : base(
20 | projectRepository,
21 | projectPublisher, ServiceLocator.Current.GetInstance(), contentChangeManager,
22 | languageSelectorFactory, ServiceLocator.Current.GetInstance(),
23 | siteConfigurationRepository, approvalService, localizationService, projectUIOptions, databaseMode)
24 | {
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.IntegrationTests/SolutionPathUtility.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0.
3 | // Derived from Microsoft.AspNetCore.Mvc.TestCommon.SolutionPathUtility
4 |
5 | using System;
6 | using System.IO;
7 |
8 | namespace Advanced.CMS.IntegrationTests
9 | {
10 | public static class SolutionPathUtility
11 | {
12 | public static string GetSolutionPath(string solutionRelativePath, string solutionName)
13 | {
14 | var applicationBasePath = Environment.CurrentDirectory; // Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default.Application.ApplicationBasePath;
15 |
16 | var directoryInfo = new DirectoryInfo(applicationBasePath);
17 | do
18 | {
19 | var solutionFileInfo = new FileInfo(Path.Combine(directoryInfo.FullName, solutionName));
20 | if (solutionFileInfo.Exists)
21 | {
22 | return Path.GetFullPath(Path.Combine(directoryInfo.FullName, solutionRelativePath));
23 | }
24 |
25 | directoryInfo = directoryInfo.Parent;
26 | }
27 | while (directoryInfo.Parent != null);
28 |
29 | throw new Exception($"Solution root could not be located using current application directory {applicationBasePath}.");
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/test/Advanced.CMS.IntegrationTests/SwitchableDatabaseMode.cs:
--------------------------------------------------------------------------------
1 | using EPiServer.Data;
2 |
3 | namespace Advanced.CMS.IntegrationTests
4 | {
5 | public class SwitchableDatabaseMode : IDatabaseMode
6 | {
7 | private readonly IDatabaseMode _inner;
8 |
9 | public SwitchableDatabaseMode(IDatabaseMode inner)
10 | {
11 | _inner = inner;
12 | }
13 |
14 | public DatabaseMode? ManualMode { get; set; }
15 |
16 | public DatabaseMode DatabaseMode => ManualMode ?? _inner.DatabaseMode;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/test/sites/TestSite/.gitignore:
--------------------------------------------------------------------------------
1 | modules/_protected/CMS/**
2 | modules/_protected/EPiServer.Cms.TinyMce/**
3 | modules/_protected/EPiServer.Cms.UI.Admin/**
4 | modules/_protected/EPiServer.Cms.UI.Settings/**
5 | modules/_protected/EPiServer.Cms.UI.VisitorGroups/**
6 | modules/_protected/Shell/**
7 |
--------------------------------------------------------------------------------
/test/sites/TestSite/Controllers/StandardPageController.cs:
--------------------------------------------------------------------------------
1 | using EPiServer.Web.Mvc;
2 | using Microsoft.AspNetCore.Mvc;
3 | using TestSite.Models;
4 |
5 | namespace TestSite.Controllers
6 | {
7 | public class StandardPageController : PageController
8 | {
9 | public IActionResult Index(StandardPage currentPage)
10 | {
11 | return View(currentPage);
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/sites/TestSite/Controllers/StartPageController.cs:
--------------------------------------------------------------------------------
1 | using EPiServer.Web.Mvc;
2 | using Microsoft.AspNetCore.Mvc;
3 | using TestSite.Models;
4 |
5 | namespace TestSite.Controllers
6 | {
7 | public class StartPageController : PageController
8 | {
9 | public IActionResult Index(StartPage currentPage)
10 | {
11 | return View(currentPage);
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/sites/TestSite/Models/EditorialBlock.cs:
--------------------------------------------------------------------------------
1 | using EPiServer.Core;
2 | using EPiServer.DataAnnotations;
3 |
4 | namespace TestSite.Models;
5 |
6 | [ContentType(GUID = "541C1C77-0040-4D05-AF42-14C165D882C7")]
7 | public class EditorialBlock : BlockData
8 | {
9 | public virtual string MainBody { get; set; }
10 | }
11 |
--------------------------------------------------------------------------------
/test/sites/TestSite/Models/GenericFile.cs:
--------------------------------------------------------------------------------
1 | using EPiServer.Core;
2 | using EPiServer.DataAnnotations;
3 | using EPiServer.Framework.DataAnnotations;
4 | using System.ComponentModel.DataAnnotations;
5 |
6 | namespace TestSite.Models
7 | {
8 | [ContentType]
9 | public class GenericFile : MediaData
10 | {
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/sites/TestSite/Models/ImageFile.cs:
--------------------------------------------------------------------------------
1 | using EPiServer.Core;
2 | using EPiServer.DataAnnotations;
3 | using EPiServer.Framework.DataAnnotations;
4 | using System.ComponentModel.DataAnnotations;
5 |
6 | namespace TestSite.Models
7 | {
8 | [ContentType]
9 | [MediaDescriptor(ExtensionString = "jpg,jpeg,jpe,ico,gif,bmp,png")]
10 | public class ImageFile : ImageData
11 | {
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/test/sites/TestSite/Models/StandardPage.cs:
--------------------------------------------------------------------------------
1 | using EPiServer.Core;
2 | using EPiServer.DataAnnotations;
3 |
4 | namespace TestSite.Models
5 | {
6 | [ContentType(GUID = "85FC1C77-0040-4D05-AF42-14C165D882C7")]
7 | public class StandardPage : PageData
8 | {
9 | public virtual ContentArea ContentArea { get; set; }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/sites/TestSite/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using EPiServer.DependencyInjection;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.Hosting;
10 | using Microsoft.Extensions.Logging;
11 |
12 | namespace TestSite
13 | {
14 | public class Program
15 | {
16 | public static void Main(string[] args)
17 | {
18 | CreateHostBuilder(args).Build().Run();
19 | }
20 |
21 | public static IHostBuilder CreateHostBuilder(string[] args) =>
22 | Host.CreateDefaultBuilder(args)
23 | .ConfigureCmsDefaults()
24 | .ConfigureWebHostDefaults(webBuilder =>
25 | {
26 | webBuilder.UseStartup();
27 | });
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/test/sites/TestSite/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:29966",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "TestSite": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "applicationUrl": "http://localhost:5000",
22 | "environmentVariables": {
23 | "ASPNETCORE_ENVIRONMENT": "Development"
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/test/sites/TestSite/SiteViewEngineLocationExpander.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Microsoft.AspNetCore.Mvc.Razor;
3 |
4 | namespace TestSite.Business.Rendering
5 | {
6 | public class SiteViewEngineLocationExpander : IViewLocationExpander
7 | {
8 | public const string BlockFolder = "~/Views/Shared/Blocks/";
9 | public const string PagePartialsFolder = "~/Views/Shared/PagePartials/";
10 |
11 | private static readonly string[] AdditionalPartialViewFormats = new[]
12 | {
13 | BlockFolder + "{0}.cshtml",
14 | PagePartialsFolder + "{0}.cshtml"
15 | };
16 |
17 | public IEnumerable ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable viewLocations)
18 | {
19 | foreach (var location in viewLocations)
20 | {
21 | yield return location;
22 | }
23 |
24 | for (int i = 0; i < AdditionalPartialViewFormats.Length; i++)
25 | {
26 | yield return AdditionalPartialViewFormats[i];
27 | }
28 | }
29 | public void PopulateValues(ViewLocationExpanderContext context) { }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/test/sites/TestSite/SkipAntiforgeryFilterProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using Microsoft.AspNetCore.Mvc.Filters;
4 | using Microsoft.AspNetCore.Mvc.ViewFeatures;
5 |
6 | namespace TestSite
7 | {
8 | public class SkipAntiforgeryFilterProvider : IFilterProvider
9 | {
10 | public int Order => int.MaxValue;
11 |
12 | public void OnProvidersExecuted(FilterProviderContext context)
13 | {
14 | }
15 |
16 | public void OnProvidersExecuting(FilterProviderContext context)
17 | {
18 | if (context == null)
19 | {
20 | throw new ArgumentNullException(nameof(context));
21 | }
22 |
23 | var FilterDescriptor = new FilterDescriptor(SkipAntiforgeryPolicy.Instance, FilterScope.Last);
24 | var filterItem = new FilterItem(FilterDescriptor, SkipAntiforgeryPolicy.Instance);
25 | context.Results.Add(filterItem);
26 | }
27 |
28 | class SkipAntiforgeryPolicy : IAntiforgeryPolicy, IAsyncAuthorizationFilter
29 | {
30 | public static readonly SkipAntiforgeryPolicy Instance = new SkipAntiforgeryPolicy();
31 |
32 | public Task OnAuthorizationAsync(AuthorizationFilterContext context) => Task.CompletedTask;
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/test/sites/TestSite/TestSite.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | false
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/test/sites/TestSite/Views/Shared/Blocks/EditorialBlock.cshtml:
--------------------------------------------------------------------------------
1 | @using EPiServer.Web.Mvc.Html
2 | @model TestSite.Models.EditorialBlock
3 |
4 | AAAAAAAAAAAAAA
5 |
6 | x.MainBody)>
7 | EEEEE
8 | @Html.DisplayFor(x => Model.MainBody)
9 |
10 |
--------------------------------------------------------------------------------
/test/sites/TestSite/Views/StandardPage/Index.cshtml:
--------------------------------------------------------------------------------
1 | @using EPiServer.Web.Mvc.Html
2 | @model TestSite.Models.StandardPage
3 |
4 |
5 |
6 |
7 |
8 | @Model.Name
9 |
10 |
11 | @Html.PropertyFor(x => x.Name)
12 | @if (Model.ContentArea != null)
13 | {
14 | Fragments count = @Model.ContentArea.Count
15 | @Html.PropertyFor(x => x.ContentArea)
16 | }
17 |
18 |
19 |
--------------------------------------------------------------------------------
/test/sites/TestSite/Views/StartPage/Index.cshtml:
--------------------------------------------------------------------------------
1 | @using EPiServer.Web.Mvc.Html
2 | @model TestSite.Models.StartPage
3 |
4 |
5 |
6 |
7 |
8 | @Model.MetaTitle
9 |
10 |
11 | @Html.PropertyFor(x => x.Name)
12 | @Html.PropertyFor(x => x.MainContentArea)
13 |
14 |
15 |
--------------------------------------------------------------------------------
/test/sites/TestSite/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/test/sites/TestSite/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "AllowedHosts": "*"
10 | }
11 |
--------------------------------------------------------------------------------
/test/sites/TestSite/module.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/test/sites/TestSite/wwwroot/Dummy.txt:
--------------------------------------------------------------------------------
1 | If wwwroot does not containe any files IWebHostingEnvironment.WebRootPath is null
2 |
--------------------------------------------------------------------------------