Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public static IServiceCollection AddPoracleServices(this IServiceCollection serv
services.AddScoped<ICleaningService, CleaningService>();
services.AddScoped<IPwebSettingService, PwebSettingService>();
services.AddSingleton<IMasterDataService, MasterDataService>();
services.AddSingleton<IRaidLevelService, RaidLevelService>();
services.AddSingleton<IPvpRankService, PvpRankService>();
services.AddScoped<IQuickPickService, QuickPickService>();
services.AddScoped<IUserGeofenceService, UserGeofenceService>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,72 +1,89 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Pgan.PoracleWebNet.Core.Abstractions.Services;

namespace Pgan.PoracleWebNet.Api.Controllers;

[Route("api/masterdata")]
public class MasterDataController(IMasterDataService masterDataService, IPoracleApiProxy poracleApiProxy) : BaseApiController
{
private readonly IMasterDataService _masterDataService = masterDataService;
private readonly IPoracleApiProxy _poracleApiProxy = poracleApiProxy;

[AllowAnonymous]
[HttpGet("pokemon")]
public async Task<IActionResult> GetPokemon()
{
var data = await this._masterDataService.GetPokemonDataAsync();
if (data == null)
{
await this._masterDataService.RefreshCacheAsync();
data = await this._masterDataService.GetPokemonDataAsync();
}

if (data == null)
{
return this.NotFound(new
{
message = "Pokemon data not available."
});
}

return this.Content(data, "application/json");
}

[AllowAnonymous]
[HttpGet("items")]
public async Task<IActionResult> GetItems()
{
var data = await this._masterDataService.GetItemDataAsync();
if (data == null)
{
await this._masterDataService.RefreshCacheAsync();
data = await this._masterDataService.GetItemDataAsync();
}

if (data == null)
{
return this.NotFound(new
{
message = "Item data not available."
});
}

return this.Content(data, "application/json");
}

[AllowAnonymous]
[HttpGet("grunts")]
public async Task<IActionResult> GetGrunts()
{
var grunts = await this._poracleApiProxy.GetGruntsAsync();
if (grunts == null)
{
return this.NotFound(new
{
message = "Grunt data not available."
});
}

return this.Content(grunts, "application/json");
}
}
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Pgan.PoracleWebNet.Core.Abstractions.Services;

namespace Pgan.PoracleWebNet.Api.Controllers;

[Route("api/masterdata")]
public class MasterDataController(
IMasterDataService masterDataService,
IPoracleApiProxy poracleApiProxy,
IRaidLevelService raidLevelService) : BaseApiController
{
private readonly IMasterDataService _masterDataService = masterDataService;
private readonly IPoracleApiProxy _poracleApiProxy = poracleApiProxy;
private readonly IRaidLevelService _raidLevelService = raidLevelService;

[AllowAnonymous]
[HttpGet("pokemon")]
public async Task<IActionResult> GetPokemon()
{
var data = await this._masterDataService.GetPokemonDataAsync();
if (data == null)
{
await this._masterDataService.RefreshCacheAsync();
data = await this._masterDataService.GetPokemonDataAsync();
}

if (data == null)
{
return this.NotFound(new
{
message = "Pokemon data not available."
});
}

return this.Content(data, "application/json");
}

[AllowAnonymous]
[HttpGet("items")]
public async Task<IActionResult> GetItems()
{
var data = await this._masterDataService.GetItemDataAsync();
if (data == null)
{
await this._masterDataService.RefreshCacheAsync();
data = await this._masterDataService.GetItemDataAsync();
}

if (data == null)
{
return this.NotFound(new
{
message = "Item data not available."
});
}

return this.Content(data, "application/json");
}

/// <summary>
/// Canonical raid-level vocabulary (currently 19 levels from the WatWowMap masterfile).
/// Cached server-side; the frontend uses this to render the level selector and
/// fall back to bare integers for any level not in the list.
/// </summary>
[AllowAnonymous]
[HttpGet("raid-levels")]
public async Task<IActionResult> GetRaidLevels()
{
var levels = await this._raidLevelService.GetAllAsync();
return this.Ok(levels);
}

[AllowAnonymous]
[HttpGet("grunts")]
public async Task<IActionResult> GetGrunts()
{
var grunts = await this._poracleApiProxy.GetGruntsAsync();
if (grunts == null)
{
return this.NotFound(new
{
message = "Grunt data not available."
});
}

return this.Content(grunts, "application/json");
}
}
14 changes: 14 additions & 0 deletions Applications/Pgan.PoracleWebNet.App/ClientApp/proxy.conf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"/api": {
"target": "http://localhost:5048",
"secure": false,
"changeOrigin": false,
"logLevel": "warn"
},
"/auth": {
"target": "http://localhost:5048",
"secure": false,
"changeOrigin": false,
"logLevel": "warn"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import {
ANY_LEVEL,
ANY_LEVEL_VALUE,
EGG_LEVELS,
isKnownLevel,
KNOWN_LEVELS,
makeCustomLevel,
MEGA_LEVELS,
OVERFLOW_RAID_LEVELS,
PRIMARY_RAID_LEVELS,
resolveLevel,
STAR_LEVELS,
} from './raid-level.models';

describe('raid-level.models (canonical 19 levels)', () => {
describe('KNOWN_LEVELS', () => {
it('has 19 entries covering integers 1-19 in order', () => {
expect(KNOWN_LEVELS.length).toBe(19);
KNOWN_LEVELS.forEach((opt, i) => expect(opt.value).toBe(i + 1));
});

it('partitions correctly by category', () => {
const byCategory = KNOWN_LEVELS.reduce<Record<string, number[]>>((acc, l) => {
(acc[l.category] ||= []).push(l.value);
return acc;
}, {});
expect(byCategory['star']).toEqual([1, 2, 3, 4, 5]);
expect(byCategory['mega']).toEqual([6, 7]);
expect(byCategory['special']).toEqual([8, 9, 10]);
expect(byCategory['shadow']).toEqual([11, 12, 13, 14, 15]);
expect(byCategory['superMega']).toEqual([16, 17]);
expect(byCategory['coordinated']).toEqual([18, 19]);
});

it('points level 7 at Mega Legendary, level 9 at Elite (fixes prior mislabel)', () => {
const seven = KNOWN_LEVELS.find(l => l.value === 7)!;
const nine = KNOWN_LEVELS.find(l => l.value === 9)!;
expect(seven.labelKey).toBe('RAIDS.LEVEL.RAID_7');
expect(seven.category).toBe('mega');
expect(nine.labelKey).toBe('RAIDS.LEVEL.RAID_9');
expect(nine.category).toBe('special');
});

it('every entry uses the RAID_N label key', () => {
KNOWN_LEVELS.forEach(opt => {
expect(opt.labelKey).toBe(`RAIDS.LEVEL.RAID_${opt.value}`);
});
});
});

describe('derived groupings', () => {
it('STAR_LEVELS is 1-5', () => {
expect(STAR_LEVELS.map(l => l.value)).toEqual([1, 2, 3, 4, 5]);
});

it('EGG_LEVELS mirrors STAR_LEVELS (eggs only have star tiers)', () => {
expect(EGG_LEVELS.map(l => l.value)).toEqual([1, 2, 3, 4, 5]);
});

it('MEGA_LEVELS is 6-7', () => {
expect(MEGA_LEVELS.map(l => l.value)).toEqual([6, 7]);
});

it('PRIMARY_RAID_LEVELS is 1-7', () => {
expect(PRIMARY_RAID_LEVELS.map(l => l.value)).toEqual([1, 2, 3, 4, 5, 6, 7]);
});

it('OVERFLOW_RAID_LEVELS is 8-19', () => {
expect(OVERFLOW_RAID_LEVELS.map(l => l.value)).toEqual([8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]);
});
});

describe('resolveLevel', () => {
it('returns ANY_LEVEL for the 9000 sentinel', () => {
expect(resolveLevel(ANY_LEVEL_VALUE)).toEqual(ANY_LEVEL);
});

it('returns the canonical option for any value 1-19', () => {
for (let v = 1; v <= 19; v++) {
const opt = resolveLevel(v);
expect(opt.value).toBe(v);
expect(opt.labelKey).toBe(`RAIDS.LEVEL.RAID_${v}`);
expect(opt.category).not.toBe('custom');
}
});

it('returns a custom option for unrecognized values (20+, negatives, 0)', () => {
expect(resolveLevel(42).category).toBe('custom');
expect(resolveLevel(20).category).toBe('custom');
expect(resolveLevel(0).category).toBe('custom');
expect(resolveLevel(-1).category).toBe('custom');
});
});

describe('isKnownLevel', () => {
it('is true for 1-19 and 9000', () => {
for (let v = 1; v <= 19; v++) expect(isKnownLevel(v)).toBe(true);
expect(isKnownLevel(ANY_LEVEL_VALUE)).toBe(true);
});

it('is false for 0, negatives, and 20+', () => {
expect(isKnownLevel(0)).toBe(false);
expect(isKnownLevel(-3)).toBe(false);
expect(isKnownLevel(20)).toBe(false);
expect(isKnownLevel(42)).toBe(false);
});
});

describe('makeCustomLevel', () => {
it('round-trips through resolveLevel', () => {
expect(resolveLevel(66)).toEqual(makeCustomLevel(66));
});
});
});
Loading
Loading