Skip to content

Commit

Permalink
feat(costs): add costs audit that returns the ahrefs API units consum…
Browse files Browse the repository at this point in the history
…ed and limit
  • Loading branch information
iuliag committed Aug 19, 2024
1 parent 57e2757 commit 6eb1eb2
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 4 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"@adobe/helix-status": "10.1.2",
"@adobe/helix-universal": "5.0.5",
"@adobe/helix-universal-logger": "3.0.18",
"@adobe/spacecat-shared-ahrefs-client": "1.4.1",
"@adobe/spacecat-shared-ahrefs-client": "https://gitpkg.now.sh/adobe/spacecat-shared/packages/spacecat-shared-ahrefs-client?ahrefs-cost",
"@adobe/spacecat-shared-data-access": "1.41.4",
"@adobe/spacecat-shared-http-utils": "1.6.5",
"@adobe/spacecat-shared-rum-api-client": "2.7.3",
Expand Down
51 changes: 51 additions & 0 deletions src/costs/handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2024 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/

import AhrefsAPIClient from '@adobe/spacecat-shared-ahrefs-client';
import { AuditBuilder } from '../common/audit-builder.js';

export async function runner(auditUrl, context) {
const { log } = context;
const ahrefsAPIClient = AhrefsAPIClient.createFrom(context);

let ahrefsCostsAuditResult;
try {
const {
result,
fullAuditRef,
} = await ahrefsAPIClient.getLimitsAndUsage();

log.info(`Retrieved Ahrefs limits and usage: ${JSON.stringify(result)}`);
ahrefsCostsAuditResult = {
usedApiUnits: result?.limits_and_usage?.units_usage_api_key,
limitApiUnits: result?.limits_and_usage?.units_limit_api_key,
fullAuditRef,
};
} catch (e) {
log.error(`Ahrefs costs type audit failed with error: ${e.message}`, e);
ahrefsCostsAuditResult = {
error: `Ahrefs costs type audit failed with error: ${e.message}`,
};
}

return {
auditResult: {
ahrefs: ahrefsCostsAuditResult,
},
fullAuditRef: ahrefsCostsAuditResult?.fullAuditRef,
};
}

export default new AuditBuilder()
.withRunner(runner)
.withMessageSender(() => {})
.build();
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import experimentation from './experimentation/handler.js';
import conversion from './conversion/handler.js';
import essExperimentationDaily from './experimentation-ess/daily.js';
import essExperimentationAll from './experimentation-ess/all.js';
import costs from './costs/handler.js';

const HANDLERS = {
apex,
Expand All @@ -43,6 +44,7 @@ const HANDLERS = {
conversion,
'experimentation-ess-daily': essExperimentationDaily,
'experimentation-ess-all': essExperimentationAll,
costs,
};

function getElapsedSeconds(startTime) {
Expand Down
103 changes: 103 additions & 0 deletions test/audits/costs.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright 2024 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/

/* eslint-env mocha */
import chai from 'chai';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import chaiAsPromised from 'chai-as-promised';
import nock from 'nock';
import { MockContextBuilder } from '../shared.js';
import { runner } from '../../src/costs/handler.js';

chai.use(sinonChai);
chai.use(chaiAsPromised);
const { expect } = chai;

const message = {
type: 'costs',
url: 'site-id',
};
const sandbox = sinon.createSandbox();

describe('Costs audit', () => {
let context;

beforeEach('setup', () => {
context = new MockContextBuilder()
.withSandbox(sandbox)
.withOverrides({
env: {
AHREFS_API_BASE_URL: 'https://ahrefs-example.com',
AHREFS_API_KEY: 'ahrefs-token',
},
})
.build(message);
});

afterEach(() => {
nock.cleanAll();
sandbox.restore();
});

it('costs audit returns ahrefs costs succesfully', async () => {
const limitsUsageResponse = {
limits_and_usage: {
subscription: 'Enterprise, billed yearly',
usage_reset_date: '2024-08-28T00:00:00Z',
units_limit_workspace: 12000000,
units_usage_workspace: 6618294,
units_limit_api_key: 1000000,
units_usage_api_key: 198771,
api_key_expiration_date: '2025-01-04T17:44:07Z',
},
};

nock('https://ahrefs-example.com')
.get('/subscription-info/limits-and-usage')
.reply(200, limitsUsageResponse);

const result = await runner('https://spacecat.com', context);

const expectedAuditResult = {
ahrefs: {
usedApiUnits: 198771,
limitApiUnits: 1000000,
fullAuditRef: 'https://ahrefs-example.com/subscription-info/limits-and-usage',
},
};

expect(result).to.eql({
auditResult: expectedAuditResult,
fullAuditRef: 'https://ahrefs-example.com/subscription-info/limits-and-usage',
});
});

it('costs audit returns error for ahrefs costs when call to ahrefs throws', async () => {
nock('https://ahrefs-example.com')
.get('/subscription-info/limits-and-usage')
.reply(500);

const result = await runner('https://spacecat.com', context);

const expectedAuditResult = {
ahrefs: {
error: 'Ahrefs costs type audit failed with error: Ahrefs API request failed with status: 500',
},
};

expect(result).to.eql({
auditResult: expectedAuditResult,
fullAuditRef: undefined,
});
});
});

0 comments on commit 6eb1eb2

Please sign in to comment.