diff --git a/config/routes.rb b/config/routes.rb
index fa7cfd65b..856b6f5a3 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -121,6 +121,7 @@ Rails.application.routes.draw do
resources :webhook_endpoints, only: :index
resource :config
resources :badges, only: %i[index edit update new create]
+ resources :display_ads, only: %i[index edit update new create destroy]
# These redirects serve as a safegaurd to prevent 404s for any Admins
# who have the old badge_achievement URLs bookmarked.
get "/badges/badge_achievements", to: redirect("/admin/badge_achievements")
diff --git a/spec/requests/admin/display_ads_spec.rb b/spec/requests/admin/display_ads_spec.rb
new file mode 100644
index 000000000..d015e7398
--- /dev/null
+++ b/spec/requests/admin/display_ads_spec.rb
@@ -0,0 +1,140 @@
+require "rails_helper"
+require "requests/shared_examples/internal_policy_dependant_request"
+
+RSpec.describe "/admin/display_ads", type: :request do
+ let(:get_resource) { get "/admin/display_ads" }
+ let(:org) { create(:organization) }
+ let(:params) do
+ { organization_id: org.id, body_markdown: "[Click here!](https://example.com)", placement_area: "sidebar_left",
+ approved: true, published: true }
+ end
+ let(:post_resource) { post "/admin/display_ads", params: params }
+
+ it_behaves_like "an InternalPolicy dependant request", DisplayAd do
+ let(:request) { get_resource }
+ end
+
+ context "when the user is not an admin" do
+ let(:user) { create(:user) }
+
+ before { sign_in user }
+
+ describe "GET /admin/display_ads" do
+ it "blocks the request" do
+ expect { get_resource }.to raise_error(Pundit::NotAuthorizedError)
+ end
+ end
+
+ describe "POST /admin/display_ads" do
+ it "blocks the request" do
+ expect { post_resource }.to raise_error(Pundit::NotAuthorizedError)
+ end
+ end
+ end
+
+ context "when the user is a super admin" do
+ let(:super_admin) { create(:user, :super_admin) }
+
+ before { sign_in super_admin }
+
+ describe "GET /admin/display_ads" do
+ it "allows the request" do
+ get_resource
+ expect(response).to have_http_status(:ok)
+ end
+ end
+
+ describe "POST /admin/display_ads" do
+ it "creates a new display_ad" do
+ expect do
+ post_resource
+ end.to change { DisplayAd.all.count }.by(1)
+ end
+ end
+
+ describe "PUT /admin/display_ads" do
+ let!(:display_ad) { create(:display_ad, approved: false) }
+
+ it "updates DisplayAd's approved value" do
+ Timecop.freeze(Time.current) do
+ expect do
+ put "/admin/display_ads/#{display_ad.id}", params: params
+ end.to change { display_ad.reload.approved }.from(false).to(true)
+ end
+ end
+ end
+
+ describe "DELETE /admin/display_ads/:id" do
+ let!(:display_ad) { create(:display_ad) }
+
+ it "deletes the Display Ad" do
+ expect do
+ delete "/admin/display_ads/#{display_ad.id}"
+ end.to change { DisplayAd.all.count }.by(-1)
+ expect(response.body).to redirect_to "/admin/display_ads"
+ end
+ end
+ end
+
+ context "when the user is a single resource admin" do
+ let(:single_resource_admin) { create(:user, :single_resource_admin, resource: DisplayAd) }
+
+ before { sign_in single_resource_admin }
+
+ describe "GET /admin/display_ads" do
+ it "allows the request" do
+ get_resource
+ expect(response).to have_http_status(:ok)
+ end
+ end
+
+ describe "POST /admin/display_ads" do
+ it "creates a new display_ad" do
+ expect do
+ post_resource
+ end.to change { DisplayAd.all.count }.by(1)
+ end
+ end
+
+ describe "PUT /admin/display_ads" do
+ let!(:display_ad) { create(:display_ad, approved: false) }
+
+ it "updates DisplayAd's approved value" do
+ Timecop.freeze(Time.current) do
+ expect do
+ put "/admin/display_ads/#{display_ad.id}", params: params
+ end.to change { display_ad.reload.approved }.from(false).to(true)
+ end
+ end
+ end
+
+ describe "DELETE /admin/display_ads/:id" do
+ let!(:display_ad) { create(:display_ad) }
+
+ it "deletes the Display Ad" do
+ expect do
+ delete "/admin/display_ads/#{display_ad.id}"
+ end.to change { DisplayAd.all.count }.by(-1)
+ expect(response.body).to redirect_to "/admin/display_ads"
+ end
+ end
+ end
+
+ context "when the user is the wrong single resource admin" do
+ let(:single_resource_admin) { create(:user, :single_resource_admin, resource: Article) }
+
+ before { sign_in single_resource_admin }
+
+ describe "GET /admin/display_ads" do
+ it "blocks the request" do
+ expect { get_resource }.to raise_error(Pundit::NotAuthorizedError)
+ end
+ end
+
+ describe "POST /admin/display_ads" do
+ it "blocks the request" do
+ expect { post_resource }.to raise_error(Pundit::NotAuthorizedError)
+ end
+ end
+ end
+end